1use std::sync::Arc;
18
19pub const BASIS_POINTS: u64 = 10_000;
21const SCALED_BASIS_POINTS: u64 = BASIS_POINTS * BASIS_POINTS;
22const COST_SCALE: u64 = 1_000_000;
23const COST_ROUNDING: u64 = COST_SCALE - 1;
24pub const ALL_PROVIDERS: u64 = u64::MAX;
26pub const ALL_REGIONS: u64 = u64::MAX;
28pub const MAX_PROVIDER_ID: u16 = 63;
30pub const MAX_CATALOG_MODELS: usize = u16::MAX as usize;
32
33#[repr(C)]
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
38pub struct KernelModel {
39 pub model_id: u32,
41 pub provider_id: u16,
43 pub quality_bps: u16,
45 pub risk_ceiling_bps: u16,
47 pub enabled: u8,
49 pub p95_latency_ms: u32,
51 pub capabilities: u64,
53 pub region_mask: u64,
55 pub input_cost_microunits_per_million_tokens: u64,
57 pub output_cost_microunits_per_million_tokens: u64,
59}
60
61#[repr(C)]
63#[derive(Clone, Copy, Debug, Eq, PartialEq)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
66pub struct KernelInput {
67 pub request_sequence: u64,
69 pub requested_model_id: u32,
71 pub input_tokens: u32,
73 pub output_tokens: u32,
75 pub business_value_microunits: i64,
77 pub budget_limit_microunits: u64,
79 pub risk_bps: u16,
81 pub confidence_bps: u16,
83 pub minimum_quality_bps: u16,
85 pub max_p95_latency_ms: u32,
87 pub required_capabilities: u64,
89 pub allowed_provider_mask: u64,
91 pub required_region_mask: u64,
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
97pub enum InputError {
98 #[error("{field} must be <= {max}, got {value}")]
99 OutOfRangeBps {
100 field: &'static str,
101 value: u16,
102 max: u16,
103 },
104}
105
106impl KernelInput {
107 pub fn validate(&self) -> Result<(), InputError> {
112 if self.risk_bps > MAX_BPS {
113 return Err(InputError::OutOfRangeBps {
114 field: "risk_bps",
115 value: self.risk_bps,
116 max: MAX_BPS,
117 });
118 }
119 if self.confidence_bps > MAX_BPS {
120 return Err(InputError::OutOfRangeBps {
121 field: "confidence_bps",
122 value: self.confidence_bps,
123 max: MAX_BPS,
124 });
125 }
126 if self.minimum_quality_bps > MAX_BPS {
127 return Err(InputError::OutOfRangeBps {
128 field: "minimum_quality_bps",
129 value: self.minimum_quality_bps,
130 max: MAX_BPS,
131 });
132 }
133 Ok(())
134 }
135}
136
137#[repr(u8)]
139#[derive(Clone, Copy, Debug, Eq, PartialEq)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub enum KernelAction {
142 ExecuteRequested = 1,
144 Substitute = 2,
146 Reject = 3,
148}
149
150impl std::fmt::Display for KernelAction {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 match self {
153 Self::ExecuteRequested => write!(f, "execute_requested"),
154 Self::Substitute => write!(f, "substitute"),
155 Self::Reject => write!(f, "reject"),
156 }
157 }
158}
159
160#[repr(u16)]
162#[derive(Clone, Copy, Debug, Eq, PartialEq)]
163#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
164pub enum KernelReason {
165 RequestedModelMaximizesUtility = 1,
167 AlternativeMaximizesUtility = 2,
169 RiskHardLimit = 100,
171 ConfidenceHardLimit = 101,
173 NoEnabledModel = 102,
175 QualityConstraint = 103,
177 LatencyConstraint = 104,
179 CapabilityConstraint = 105,
181 ProviderConstraint = 106,
183 RegionConstraint = 107,
185 BudgetConstraint = 108,
187 NonPositiveUtility = 109,
189 RiskCeilingConstraint = 110,
191}
192
193impl std::fmt::Display for KernelReason {
194 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195 match self {
196 Self::RequestedModelMaximizesUtility => write!(f, "requested_model_maximizes_utility"),
197 Self::AlternativeMaximizesUtility => write!(f, "alternative_maximizes_utility"),
198 Self::RiskHardLimit => write!(f, "risk_hard_limit"),
199 Self::ConfidenceHardLimit => write!(f, "confidence_hard_limit"),
200 Self::NoEnabledModel => write!(f, "no_enabled_model"),
201 Self::QualityConstraint => write!(f, "quality_constraint"),
202 Self::LatencyConstraint => write!(f, "latency_constraint"),
203 Self::CapabilityConstraint => write!(f, "capability_constraint"),
204 Self::ProviderConstraint => write!(f, "provider_constraint"),
205 Self::RegionConstraint => write!(f, "region_constraint"),
206 Self::BudgetConstraint => write!(f, "budget_constraint"),
207 Self::NonPositiveUtility => write!(f, "non_positive_utility"),
208 Self::RiskCeilingConstraint => write!(f, "risk_ceiling_constraint"),
209 }
210 }
211}
212
213#[repr(C)]
215#[derive(Clone, Copy, Debug, Eq, PartialEq)]
216#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
217#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
218pub struct KernelDecision {
219 pub request_sequence: u64,
221 pub action: KernelAction,
223 pub reason: KernelReason,
225 pub selected_model_id: u32,
227 pub selected_model_index: u16,
229 pub estimated_cost_microunits: u64,
231 pub expected_utility_microunits: i64,
233 pub counterfactual_model_id: u32,
235 pub counterfactual_utility_microunits: i64,
237 pub evaluated_models: u16,
239 pub eligible_models: u16,
241 pub policy_epoch: u64,
243 pub catalog_epoch: u64,
245}
246
247impl KernelDecision {
248 #[must_use]
250 pub const fn is_executable(&self) -> bool {
251 matches!(
252 self.action,
253 KernelAction::ExecuteRequested | KernelAction::Substitute
254 )
255 }
256
257 #[must_use]
259 pub const fn is_requested_execution(&self) -> bool {
260 matches!(self.action, KernelAction::ExecuteRequested)
261 }
262
263 #[must_use]
265 pub const fn is_substitution(&self) -> bool {
266 matches!(self.action, KernelAction::Substitute)
267 }
268
269 #[must_use]
271 pub const fn is_rejected(&self) -> bool {
272 matches!(self.action, KernelAction::Reject)
273 }
274}
275
276#[derive(Clone, Debug)]
284pub struct PolicySnapshot {
285 pub policy_epoch: u64,
286 pub catalog_epoch: u64,
287 pub hard_risk_limit_bps: u16,
288 pub minimum_confidence_bps: u16,
289 pub risk_penalty_multiplier_bps: u16,
290 pub latency_penalty_microunits_per_ms: u64,
297 max_quality_bps: u16,
298 max_p95_latency_ms: u32,
299 max_input_cost: u64,
300 max_output_cost: u64,
301 models: Arc<[KernelModel]>,
302}
303
304#[derive(Clone, Copy)]
305struct Candidate {
306 model_id: u32,
307 model_index: u16,
308 quality_bps: u16,
309 cost: u64,
310 utility: i64,
311}
312
313#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
315#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
316pub struct RejectionHistogram {
317 pub disabled: u16,
319 pub quality: u16,
321 pub risk_ceiling: u16,
323 pub latency: u16,
325 pub capability: u16,
327 pub provider: u16,
329 pub region: u16,
331 pub budget: u16,
333 pub utility: u16,
335}
336
337#[derive(Clone, Copy, Debug, PartialEq, Eq)]
339#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
340pub struct DecisionTrace {
341 pub rejections: RejectionHistogram,
342 pub evaluated_models: u16,
343 pub eligible_models: u16,
344}
345
346pub const MAX_BPS: u16 = 10_000;
348
349pub const MAX_RISK_PENALTY_MULTIPLIER_BPS: u16 = 50_000;
351
352#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
354pub enum PolicyError {
355 #[error("model catalog is empty")]
356 EmptyCatalog,
357 #[error("duplicate model_id {model_id}")]
358 DuplicateModelId { model_id: u32 },
359 #[error("model_id {model_id} has provider_id {provider_id} > MAX_PROVIDER_ID")]
360 InvalidProviderId { model_id: u32, provider_id: u16 },
361 #[error("no enabled models in catalog")]
362 NoEnabledModels,
363 #[error("{field} must be <= {max}, got {value}")]
364 OutOfRangeBps {
365 field: &'static str,
366 value: u16,
367 max: u16,
368 },
369}
370
371#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
373pub enum TrustPolicyError {
374 #[error("policy validation failed: {0}")]
375 Policy(#[from] PolicyError),
376 #[error("model catalog has {len} entries; maximum is {max}")]
377 CatalogTooLarge { len: usize, max: usize },
378 #[error("model_id 0 is reserved for decisions with no selected model")]
379 ReservedModelId,
380 #[error("model_id {model_id} has non-canonical enabled flag {value}; expected 0 or 1")]
381 InvalidEnabledFlag { model_id: u32, value: u8 },
382}
383
384type RejectionCounts = RejectionHistogram;
385
386impl PolicySnapshot {
387 pub fn new_unchecked(
398 policy_epoch: u64,
399 catalog_epoch: u64,
400 hard_risk_limit_bps: u16,
401 minimum_confidence_bps: u16,
402 risk_penalty_multiplier_bps: u16,
403 latency_penalty_microunits_per_ms: u64,
404 models: Vec<KernelModel>,
405 ) -> Self {
406 let max_quality_bps = models
407 .iter()
408 .map(|model| model.quality_bps)
409 .max()
410 .unwrap_or_default();
411 let max_p95_latency_ms = models
412 .iter()
413 .map(|model| model.p95_latency_ms)
414 .max()
415 .unwrap_or_default();
416 let max_input_cost = models
417 .iter()
418 .map(|model| model.input_cost_microunits_per_million_tokens)
419 .max()
420 .unwrap_or_default();
421 let max_output_cost = models
422 .iter()
423 .map(|model| model.output_cost_microunits_per_million_tokens)
424 .max()
425 .unwrap_or_default();
426 Self {
427 policy_epoch,
428 catalog_epoch,
429 hard_risk_limit_bps,
430 minimum_confidence_bps,
431 risk_penalty_multiplier_bps,
432 latency_penalty_microunits_per_ms,
433 max_quality_bps,
434 max_p95_latency_ms,
435 max_input_cost,
436 max_output_cost,
437 models: Arc::from(models),
438 }
439 }
440
441 #[deprecated(
443 since = "0.3.9",
444 note = "use PolicySnapshot::try_new for validated snapshots or new_unchecked for tests"
445 )]
446 pub fn new(
447 policy_epoch: u64,
448 catalog_epoch: u64,
449 hard_risk_limit_bps: u16,
450 minimum_confidence_bps: u16,
451 risk_penalty_multiplier_bps: u16,
452 latency_penalty_microunits_per_ms: u64,
453 models: Vec<KernelModel>,
454 ) -> Self {
455 Self::new_unchecked(
456 policy_epoch,
457 catalog_epoch,
458 hard_risk_limit_bps,
459 minimum_confidence_bps,
460 risk_penalty_multiplier_bps,
461 latency_penalty_microunits_per_ms,
462 models,
463 )
464 }
465
466 pub fn models(&self) -> &[KernelModel] {
468 &self.models
469 }
470
471 pub fn validate(&self) -> Result<(), PolicyError> {
473 if self.hard_risk_limit_bps > MAX_BPS {
474 return Err(PolicyError::OutOfRangeBps {
475 field: "hard_risk_limit_bps",
476 value: self.hard_risk_limit_bps,
477 max: MAX_BPS,
478 });
479 }
480 if self.minimum_confidence_bps > MAX_BPS {
481 return Err(PolicyError::OutOfRangeBps {
482 field: "minimum_confidence_bps",
483 value: self.minimum_confidence_bps,
484 max: MAX_BPS,
485 });
486 }
487 if self.risk_penalty_multiplier_bps > MAX_RISK_PENALTY_MULTIPLIER_BPS {
488 return Err(PolicyError::OutOfRangeBps {
489 field: "risk_penalty_multiplier_bps",
490 value: self.risk_penalty_multiplier_bps,
491 max: MAX_RISK_PENALTY_MULTIPLIER_BPS,
492 });
493 }
494 if self.models.is_empty() {
495 return Err(PolicyError::EmptyCatalog);
496 }
497 let mut seen = std::collections::HashSet::new();
498 let mut any_enabled = false;
499 for model in self.models.iter() {
500 if !seen.insert(model.model_id) {
501 return Err(PolicyError::DuplicateModelId {
502 model_id: model.model_id,
503 });
504 }
505 if model.provider_id > MAX_PROVIDER_ID {
506 return Err(PolicyError::InvalidProviderId {
507 model_id: model.model_id,
508 provider_id: model.provider_id,
509 });
510 }
511 if model.quality_bps > MAX_BPS {
512 return Err(PolicyError::OutOfRangeBps {
513 field: "model.quality_bps",
514 value: model.quality_bps,
515 max: MAX_BPS,
516 });
517 }
518 if model.risk_ceiling_bps > MAX_BPS {
519 return Err(PolicyError::OutOfRangeBps {
520 field: "model.risk_ceiling_bps",
521 value: model.risk_ceiling_bps,
522 max: MAX_BPS,
523 });
524 }
525 if model.enabled != 0 {
526 any_enabled = true;
527 }
528 }
529 if !any_enabled {
530 return Err(PolicyError::NoEnabledModels);
531 }
532 Ok(())
533 }
534
535 pub fn try_new(
540 policy_epoch: u64,
541 catalog_epoch: u64,
542 hard_risk_limit_bps: u16,
543 minimum_confidence_bps: u16,
544 risk_penalty_multiplier_bps: u16,
545 latency_penalty_microunits_per_ms: u64,
546 models: Vec<KernelModel>,
547 ) -> Result<Self, PolicyError> {
548 let snapshot = Self::new_unchecked(
549 policy_epoch,
550 catalog_epoch,
551 hard_risk_limit_bps,
552 minimum_confidence_bps,
553 risk_penalty_multiplier_bps,
554 latency_penalty_microunits_per_ms,
555 models,
556 );
557 snapshot.validate()?;
558 Ok(snapshot)
559 }
560
561 pub fn try_new_trusted(
568 policy_epoch: u64,
569 catalog_epoch: u64,
570 hard_risk_limit_bps: u16,
571 minimum_confidence_bps: u16,
572 risk_penalty_multiplier_bps: u16,
573 latency_penalty_microunits_per_ms: u64,
574 mut models: Vec<KernelModel>,
575 ) -> Result<Self, TrustPolicyError> {
576 if models.len() > MAX_CATALOG_MODELS {
577 return Err(TrustPolicyError::CatalogTooLarge {
578 len: models.len(),
579 max: MAX_CATALOG_MODELS,
580 });
581 }
582 if models.iter().any(|model| model.model_id == 0) {
583 return Err(TrustPolicyError::ReservedModelId);
584 }
585 if let Some(model) = models.iter().find(|model| model.enabled > 1) {
586 return Err(TrustPolicyError::InvalidEnabledFlag {
587 model_id: model.model_id,
588 value: model.enabled,
589 });
590 }
591 models.sort_by_key(|model| model.model_id);
592 let snapshot = Self::new_unchecked(
593 policy_epoch,
594 catalog_epoch,
595 hard_risk_limit_bps,
596 minimum_confidence_bps,
597 risk_penalty_multiplier_bps,
598 latency_penalty_microunits_per_ms,
599 models,
600 );
601 snapshot.validate()?;
602 Ok(snapshot)
603 }
604
605 pub fn prescribe_batch(&self, inputs: &[KernelInput]) -> Vec<KernelDecision> {
607 inputs.iter().map(|&input| self.prescribe(input)).collect()
608 }
609
610 pub fn prescribe_batch_checked(
613 &self,
614 inputs: &[KernelInput],
615 ) -> Result<Vec<KernelDecision>, InputError> {
616 for input in inputs {
617 input.validate()?;
618 }
619 Ok(self.prescribe_batch(inputs))
620 }
621
622 pub fn prescribe_with_trace(&self, input: KernelInput) -> (KernelDecision, DecisionTrace) {
624 let (decision, rejections) = self.prescribe_inner(input);
625 let trace = DecisionTrace {
626 rejections,
627 evaluated_models: decision.evaluated_models,
628 eligible_models: decision.eligible_models,
629 };
630 (decision, trace)
631 }
632
633 pub fn prescribe_with_trace_checked(
635 &self,
636 input: KernelInput,
637 ) -> Result<(KernelDecision, DecisionTrace), InputError> {
638 input.validate()?;
639 Ok(self.prescribe_with_trace(input))
640 }
641
642 #[must_use]
653 pub fn prescribe(&self, input: KernelInput) -> KernelDecision {
654 self.prescribe_inner(input).0
655 }
656
657 pub fn prescribe_checked(&self, input: KernelInput) -> Result<KernelDecision, InputError> {
663 input.validate()?;
664 Ok(self.prescribe(input))
665 }
666
667 #[must_use]
672 pub fn utility_for_model(&self, input: KernelInput, model_id: u32) -> Option<i64> {
673 if input.risk_bps >= self.hard_risk_limit_bps {
674 return None;
675 }
676 if input.confidence_bps < self.minimum_confidence_bps {
677 return None;
678 }
679 let model = self.models.iter().find(|m| m.model_id == model_id)?;
680
681 if model.enabled == 0 {
682 return None;
683 }
684 if model.quality_bps < input.minimum_quality_bps {
685 return None;
686 }
687 if input.max_p95_latency_ms > 0 && model.p95_latency_ms > input.max_p95_latency_ms {
688 return None;
689 }
690 if model.capabilities & input.required_capabilities != input.required_capabilities {
691 return None;
692 }
693 if model.provider_id > MAX_PROVIDER_ID {
694 return None;
695 }
696 if input.allowed_provider_mask != ALL_PROVIDERS
697 && input.allowed_provider_mask & (1_u64 << model.provider_id) == 0
698 {
699 return None;
700 }
701 if input.required_region_mask != 0 && model.region_mask & input.required_region_mask == 0 {
702 return None;
703 }
704 if input.risk_bps > model.risk_ceiling_bps {
705 return None;
706 }
707
708 let all_costs_fit = self.all_costs_fit_u64(input.input_tokens, input.output_tokens);
709 let cost = if all_costs_fit {
710 model_cost_fast(model, input.input_tokens, input.output_tokens)
711 } else {
712 model_cost_reference(model, input.input_tokens, input.output_tokens)
713 };
714 if cost > input.budget_limit_microunits {
715 return None;
716 }
717
718 let value = input.business_value_microunits.max(0) as u64;
719 let confidence_bps = u64::from(input.confidence_bps);
720 let quality_prefix = value.checked_mul(confidence_bps).filter(|prefix| {
721 prefix
722 .checked_mul(u64::from(self.max_quality_bps))
723 .is_some()
724 });
725 let risk_penalty = scaled_term_exact(
726 value,
727 u64::from(input.risk_bps),
728 u64::from(self.risk_penalty_multiplier_bps),
729 );
730 let all_latencies_fit = u64::from(self.max_p95_latency_ms)
731 .checked_mul(self.latency_penalty_microunits_per_ms)
732 .is_some();
733 let quality_adjusted = quality_prefix.map_or_else(
734 || scaled_term_reference(value, confidence_bps, u64::from(model.quality_bps)),
735 |prefix| {
736 i128::from(prefix.wrapping_mul(u64::from(model.quality_bps)) / SCALED_BASIS_POINTS)
737 },
738 );
739 let latency_penalty = if all_latencies_fit {
740 i128::from(
741 u64::from(model.p95_latency_ms)
742 .wrapping_mul(self.latency_penalty_microunits_per_ms),
743 )
744 } else {
745 i128::from(model.p95_latency_ms) * i128::from(self.latency_penalty_microunits_per_ms)
746 };
747 let utility =
748 clamp_i128_to_i64(quality_adjusted - risk_penalty - i128::from(cost) - latency_penalty);
749 if utility <= 0 {
750 return None;
751 }
752 Some(utility)
753 }
754
755 fn prescribe_inner(&self, input: KernelInput) -> (KernelDecision, RejectionHistogram) {
756 if input.risk_bps >= self.hard_risk_limit_bps {
757 return self.reject(input, KernelReason::RiskHardLimit, 0, 0);
758 }
759 if input.confidence_bps < self.minimum_confidence_bps {
760 return self.reject(input, KernelReason::ConfidenceHardLimit, 0, 0);
761 }
762
763 let mut best: Option<Candidate> = None;
764 let mut second: Option<Candidate> = None;
765 let mut eligible_models = 0_u16;
766 let mut rejected = RejectionCounts::default();
767
768 let value = input.business_value_microunits.max(0) as u64;
769 let confidence_bps = u64::from(input.confidence_bps);
770 let quality_prefix = value.checked_mul(confidence_bps).filter(|prefix| {
771 prefix
772 .checked_mul(u64::from(self.max_quality_bps))
773 .is_some()
774 });
775 let risk_penalty = scaled_term_exact(
776 value,
777 u64::from(input.risk_bps),
778 u64::from(self.risk_penalty_multiplier_bps),
779 );
780 let all_costs_fit = self.all_costs_fit_u64(input.input_tokens, input.output_tokens);
781 let all_latencies_fit = u64::from(self.max_p95_latency_ms)
782 .checked_mul(self.latency_penalty_microunits_per_ms)
783 .is_some();
784
785 let check_provider = input.allowed_provider_mask != ALL_PROVIDERS;
786 let check_region = input.required_region_mask != 0;
787 let check_latency = input.max_p95_latency_ms > 0;
788 let latency_pen_per_ms = self.latency_penalty_microunits_per_ms;
789
790 for (index, model) in self.models.iter().enumerate() {
791 if model.enabled == 0 {
793 rejected.disabled += 1;
794 continue;
795 }
796 if model.quality_bps < input.minimum_quality_bps {
797 rejected.quality += 1;
798 continue;
799 }
800 if check_latency && model.p95_latency_ms > input.max_p95_latency_ms {
801 rejected.latency += 1;
802 continue;
803 }
804 if model.capabilities & input.required_capabilities != input.required_capabilities {
805 rejected.capability += 1;
806 continue;
807 }
808 if model.provider_id > MAX_PROVIDER_ID {
811 rejected.provider += 1;
812 continue;
813 }
814 if check_provider && input.allowed_provider_mask & (1_u64 << model.provider_id) == 0 {
815 rejected.provider += 1;
816 continue;
817 }
818 if check_region && model.region_mask & input.required_region_mask == 0 {
819 rejected.region += 1;
820 continue;
821 }
822 if input.risk_bps > model.risk_ceiling_bps {
823 rejected.risk_ceiling += 1;
824 continue;
825 }
826
827 let cost = if all_costs_fit {
828 model_cost_fast(model, input.input_tokens, input.output_tokens)
829 } else {
830 model_cost_reference(model, input.input_tokens, input.output_tokens)
831 };
832 if cost > input.budget_limit_microunits {
833 rejected.budget += 1;
834 continue;
835 }
836
837 let quality_adjusted = quality_prefix.map_or_else(
838 || scaled_term_reference(value, confidence_bps, u64::from(model.quality_bps)),
839 |prefix| {
840 i128::from(
842 prefix.wrapping_mul(u64::from(model.quality_bps)) / SCALED_BASIS_POINTS,
843 )
844 },
845 );
846 let latency_penalty = if all_latencies_fit {
847 i128::from(u64::from(model.p95_latency_ms).wrapping_mul(latency_pen_per_ms))
848 } else {
849 i128::from(model.p95_latency_ms) * i128::from(latency_pen_per_ms)
850 };
851 let utility = clamp_i128_to_i64(
852 quality_adjusted - risk_penalty - i128::from(cost) - latency_penalty,
853 );
854
855 if utility <= 0 {
856 rejected.utility += 1;
857 continue;
858 }
859 eligible_models = eligible_models.saturating_add(1);
860
861 let candidate = Candidate {
862 model_id: model.model_id,
863 model_index: u16::try_from(index).unwrap_or(u16::MAX),
864 quality_bps: model.quality_bps,
865 cost,
866 utility,
867 };
868 match best {
869 None => best = Some(candidate),
870 Some(current) if candidate_better(candidate, current) => {
871 second = best;
872 best = Some(candidate);
873 }
874 _ => {
875 if second.is_none_or(|s| candidate_better(candidate, s)) {
876 second = Some(candidate);
877 }
878 }
879 }
880 }
881
882 let evaluated_models = u16::try_from(self.models.len()).unwrap_or(u16::MAX);
883 let Some(best) = best else {
884 let decision = self
885 .reject(
886 input,
887 dominant_rejection_reason(&rejected),
888 evaluated_models,
889 eligible_models,
890 )
891 .0;
892 return (decision, rejected);
893 };
894 let action = if best.model_id == input.requested_model_id {
895 KernelAction::ExecuteRequested
896 } else {
897 KernelAction::Substitute
898 };
899 (
900 KernelDecision {
901 request_sequence: input.request_sequence,
902 action,
903 reason: if action == KernelAction::ExecuteRequested {
904 KernelReason::RequestedModelMaximizesUtility
905 } else {
906 KernelReason::AlternativeMaximizesUtility
907 },
908 selected_model_id: best.model_id,
909 selected_model_index: best.model_index,
910 estimated_cost_microunits: best.cost,
911 expected_utility_microunits: best.utility,
912 counterfactual_model_id: second.map_or(0, |candidate| candidate.model_id),
913 counterfactual_utility_microunits: second.map_or(0, |candidate| candidate.utility),
914 evaluated_models,
915 eligible_models,
916 policy_epoch: self.policy_epoch,
917 catalog_epoch: self.catalog_epoch,
918 },
919 rejected,
920 )
921 }
922
923 #[inline]
924 fn all_costs_fit_u64(&self, input_tokens: u32, output_tokens: u32) -> bool {
925 let input = u64::from(input_tokens)
926 .checked_mul(self.max_input_cost)
927 .and_then(|value| value.checked_add(COST_ROUNDING));
928 let output = u64::from(output_tokens)
929 .checked_mul(self.max_output_cost)
930 .and_then(|value| value.checked_add(COST_ROUNDING));
931 input
932 .zip(output)
933 .is_some_and(|(input, output)| input.checked_add(output).is_some())
934 }
935
936 fn reject(
940 &self,
941 input: KernelInput,
942 reason: KernelReason,
943 evaluated_models: u16,
944 eligible_models: u16,
945 ) -> (KernelDecision, RejectionHistogram) {
946 (
947 KernelDecision {
948 request_sequence: input.request_sequence,
949 action: KernelAction::Reject,
950 reason,
951 selected_model_id: 0,
952 selected_model_index: u16::MAX,
953 estimated_cost_microunits: 0,
954 expected_utility_microunits: 0,
955 counterfactual_model_id: 0,
956 counterfactual_utility_microunits: 0,
957 evaluated_models,
958 eligible_models,
959 policy_epoch: self.policy_epoch,
960 catalog_epoch: self.catalog_epoch,
961 },
962 RejectionHistogram::default(),
963 )
964 }
965}
966
967#[inline(always)]
968fn model_cost_fast(model: &KernelModel, input_tokens: u32, output_tokens: u32) -> u64 {
969 let input = u64::from(input_tokens)
970 .wrapping_mul(model.input_cost_microunits_per_million_tokens)
971 .wrapping_add(COST_ROUNDING)
972 / COST_SCALE;
973 let output = u64::from(output_tokens)
974 .wrapping_mul(model.output_cost_microunits_per_million_tokens)
975 .wrapping_add(COST_ROUNDING)
976 / COST_SCALE;
977 input.wrapping_add(output)
978}
979
980fn model_cost_reference(model: &KernelModel, input_tokens: u32, output_tokens: u32) -> u64 {
981 let input = u128::from(input_tokens)
982 .saturating_mul(u128::from(model.input_cost_microunits_per_million_tokens))
983 .saturating_add(u128::from(COST_ROUNDING))
984 / u128::from(COST_SCALE);
985 let output = u128::from(output_tokens)
986 .saturating_mul(u128::from(model.output_cost_microunits_per_million_tokens))
987 .saturating_add(u128::from(COST_ROUNDING))
988 / u128::from(COST_SCALE);
989 u64::try_from(input.saturating_add(output)).unwrap_or(u64::MAX)
990}
991
992#[inline]
993fn scaled_term_exact(value: u64, first_bps: u64, second_bps: u64) -> i128 {
994 value
995 .checked_mul(first_bps)
996 .and_then(|value| value.checked_mul(second_bps))
997 .map_or_else(
998 || scaled_term_reference(value, first_bps, second_bps),
999 |numerator| i128::from(numerator / SCALED_BASIS_POINTS),
1000 )
1001}
1002
1003#[inline]
1004fn scaled_term_reference(value: u64, first_bps: u64, second_bps: u64) -> i128 {
1005 i128::from(value) * i128::from(first_bps) * i128::from(second_bps)
1006 / i128::from(SCALED_BASIS_POINTS)
1007}
1008
1009#[inline(always)]
1011fn candidate_better(left: Candidate, right: Candidate) -> bool {
1012 left.utility > right.utility
1013 || (left.utility == right.utility && left.cost < right.cost)
1014 || (left.utility == right.utility
1015 && left.cost == right.cost
1016 && left.quality_bps > right.quality_bps)
1017 || (left.utility == right.utility
1018 && left.cost == right.cost
1019 && left.quality_bps == right.quality_bps
1020 && left.model_id < right.model_id)
1021}
1022
1023fn dominant_rejection_reason(counts: &RejectionCounts) -> KernelReason {
1024 let candidates = [
1025 (counts.capability, KernelReason::CapabilityConstraint),
1026 (counts.region, KernelReason::RegionConstraint),
1027 (counts.provider, KernelReason::ProviderConstraint),
1028 (counts.quality, KernelReason::QualityConstraint),
1029 (counts.risk_ceiling, KernelReason::RiskCeilingConstraint),
1030 (counts.latency, KernelReason::LatencyConstraint),
1031 (counts.budget, KernelReason::BudgetConstraint),
1032 (counts.utility, KernelReason::NonPositiveUtility),
1033 (counts.disabled, KernelReason::NoEnabledModel),
1034 ];
1035 candidates
1036 .into_iter()
1037 .max_by_key(|(count, _)| *count)
1038 .filter(|(count, _)| *count > 0)
1039 .map_or(KernelReason::NoEnabledModel, |(_, reason)| reason)
1040}
1041
1042fn clamp_i128_to_i64(value: i128) -> i64 {
1043 value.clamp(i128::from(i64::MIN), i128::from(i64::MAX)) as i64
1044}
1045
1046#[cfg(test)]
1047mod tests {
1048 use std::{hint::black_box, time::Instant};
1049
1050 use proptest::prelude::*;
1051
1052 use super::*;
1053
1054 const TOOLS: u64 = 1 << 0;
1055 const REGION_EU: u64 = 1 << 0;
1056
1057 fn snapshot() -> PolicySnapshot {
1058 PolicySnapshot::new_unchecked(
1059 7,
1060 11,
1061 9_600,
1062 5_500,
1063 10_000,
1064 2,
1065 vec![
1066 KernelModel {
1067 model_id: 10,
1068 provider_id: 0,
1069 quality_bps: 7_500,
1070 risk_ceiling_bps: 9_500,
1071 enabled: 1,
1072 p95_latency_ms: 180,
1073 capabilities: TOOLS,
1074 region_mask: REGION_EU,
1075 input_cost_microunits_per_million_tokens: 150_000,
1076 output_cost_microunits_per_million_tokens: 600_000,
1077 },
1078 KernelModel {
1079 model_id: 20,
1080 provider_id: 1,
1081 quality_bps: 9_500,
1082 risk_ceiling_bps: 9_500,
1083 enabled: 1,
1084 p95_latency_ms: 450,
1085 capabilities: TOOLS,
1086 region_mask: REGION_EU,
1087 input_cost_microunits_per_million_tokens: 2_500_000,
1088 output_cost_microunits_per_million_tokens: 10_000_000,
1089 },
1090 ],
1091 )
1092 }
1093
1094 fn input() -> KernelInput {
1095 KernelInput {
1096 request_sequence: 1,
1097 requested_model_id: 20,
1098 input_tokens: 2_000,
1099 output_tokens: 500,
1100 business_value_microunits: 100_000_000,
1101 budget_limit_microunits: 20_000_000,
1102 risk_bps: 1_000,
1103 confidence_bps: 9_000,
1104 minimum_quality_bps: 7_000,
1105 max_p95_latency_ms: 1_000,
1106 required_capabilities: TOOLS,
1107 allowed_provider_mask: ALL_PROVIDERS,
1108 required_region_mask: REGION_EU,
1109 }
1110 }
1111
1112 fn prescribe_reference(snapshot: &PolicySnapshot, input: KernelInput) -> KernelDecision {
1113 if input.risk_bps >= snapshot.hard_risk_limit_bps {
1114 return snapshot.reject(input, KernelReason::RiskHardLimit, 0, 0).0;
1115 }
1116 if input.confidence_bps < snapshot.minimum_confidence_bps {
1117 return snapshot
1118 .reject(input, KernelReason::ConfidenceHardLimit, 0, 0)
1119 .0;
1120 }
1121
1122 let mut best: Option<Candidate> = None;
1123 let mut second: Option<Candidate> = None;
1124 let mut eligible_models = 0_u16;
1125 let mut rejected = RejectionCounts::default();
1126 let value = input.business_value_microunits.max(0) as u64;
1127 let risk_penalty = scaled_term_reference(
1128 value,
1129 u64::from(input.risk_bps),
1130 u64::from(snapshot.risk_penalty_multiplier_bps),
1131 );
1132
1133 for (index, model) in snapshot.models.iter().enumerate() {
1134 if model.enabled == 0 {
1135 rejected.disabled += 1;
1136 continue;
1137 }
1138 if model.quality_bps < input.minimum_quality_bps {
1139 rejected.quality += 1;
1140 continue;
1141 }
1142 if input.max_p95_latency_ms > 0 && model.p95_latency_ms > input.max_p95_latency_ms {
1143 rejected.latency += 1;
1144 continue;
1145 }
1146 if model.capabilities & input.required_capabilities != input.required_capabilities {
1147 rejected.capability += 1;
1148 continue;
1149 }
1150 if model.provider_id > MAX_PROVIDER_ID {
1151 rejected.provider += 1;
1152 continue;
1153 }
1154 if input.allowed_provider_mask != ALL_PROVIDERS
1155 && input.allowed_provider_mask & (1_u64 << model.provider_id) == 0
1156 {
1157 rejected.provider += 1;
1158 continue;
1159 }
1160 if input.required_region_mask != 0
1161 && model.region_mask & input.required_region_mask == 0
1162 {
1163 rejected.region += 1;
1164 continue;
1165 }
1166 if input.risk_bps > model.risk_ceiling_bps {
1167 rejected.risk_ceiling += 1;
1168 continue;
1169 }
1170
1171 let cost = model_cost_reference(model, input.input_tokens, input.output_tokens);
1172 if cost > input.budget_limit_microunits {
1173 rejected.budget += 1;
1174 continue;
1175 }
1176 let quality_adjusted = scaled_term_reference(
1177 value,
1178 u64::from(input.confidence_bps),
1179 u64::from(model.quality_bps),
1180 );
1181 let latency_penalty = i128::from(model.p95_latency_ms)
1182 * i128::from(snapshot.latency_penalty_microunits_per_ms);
1183 let utility = clamp_i128_to_i64(
1184 quality_adjusted - risk_penalty - i128::from(cost) - latency_penalty,
1185 );
1186 if utility <= 0 {
1187 rejected.utility += 1;
1188 continue;
1189 }
1190 eligible_models = eligible_models.saturating_add(1);
1191 let candidate = Candidate {
1192 model_id: model.model_id,
1193 model_index: u16::try_from(index).unwrap_or(u16::MAX),
1194 quality_bps: model.quality_bps,
1195 cost,
1196 utility,
1197 };
1198 if best.is_none_or(|current| candidate_better(candidate, current)) {
1199 second = best;
1200 best = Some(candidate);
1201 } else if second.is_none_or(|current| candidate_better(candidate, current)) {
1202 second = Some(candidate);
1203 }
1204 }
1205
1206 let evaluated_models = u16::try_from(snapshot.models.len()).unwrap_or(u16::MAX);
1207 let Some(best) = best else {
1208 return snapshot
1209 .reject(
1210 input,
1211 dominant_rejection_reason(&rejected),
1212 evaluated_models,
1213 eligible_models,
1214 )
1215 .0;
1216 };
1217 let action = if best.model_id == input.requested_model_id {
1218 KernelAction::ExecuteRequested
1219 } else {
1220 KernelAction::Substitute
1221 };
1222 KernelDecision {
1223 request_sequence: input.request_sequence,
1224 action,
1225 reason: if action == KernelAction::ExecuteRequested {
1226 KernelReason::RequestedModelMaximizesUtility
1227 } else {
1228 KernelReason::AlternativeMaximizesUtility
1229 },
1230 selected_model_id: best.model_id,
1231 selected_model_index: best.model_index,
1232 estimated_cost_microunits: best.cost,
1233 expected_utility_microunits: best.utility,
1234 counterfactual_model_id: second.map_or(0, |candidate| candidate.model_id),
1235 counterfactual_utility_microunits: second.map_or(0, |candidate| candidate.utility),
1236 evaluated_models,
1237 eligible_models,
1238 policy_epoch: snapshot.policy_epoch,
1239 catalog_epoch: snapshot.catalog_epoch,
1240 }
1241 }
1242
1243 #[test]
1244 fn prescribes_maximum_utility_not_minimum_price() {
1245 let decision = snapshot().prescribe(input());
1246 assert_eq!(decision.action, KernelAction::ExecuteRequested);
1247 assert_eq!(decision.selected_model_id, 20);
1248 assert_eq!(decision.counterfactual_model_id, 10);
1249 assert!(decision.expected_utility_microunits > decision.counterfactual_utility_microunits);
1250 }
1251
1252 #[test]
1253 fn hard_budget_can_prescribe_substitution() {
1254 let mut request = input();
1255 request.budget_limit_microunits = 1_000;
1256 let decision = snapshot().prescribe(request);
1257 assert_eq!(decision.action, KernelAction::Substitute);
1258 assert_eq!(decision.selected_model_id, 10);
1259 }
1260
1261 #[test]
1262 fn decision_action_helpers_match_action() {
1263 let requested = snapshot().prescribe(input());
1264 assert!(requested.is_executable());
1265 assert!(requested.is_requested_execution());
1266 assert!(!requested.is_substitution());
1267 assert!(!requested.is_rejected());
1268
1269 let mut substitute_input = input();
1270 substitute_input.budget_limit_microunits = 1_000;
1271 let substitute = snapshot().prescribe(substitute_input);
1272 assert!(substitute.is_executable());
1273 assert!(!substitute.is_requested_execution());
1274 assert!(substitute.is_substitution());
1275 assert!(!substitute.is_rejected());
1276
1277 let mut rejected_input = input();
1278 rejected_input.risk_bps = 9_900;
1279 let rejected = snapshot().prescribe(rejected_input);
1280 assert!(!rejected.is_executable());
1281 assert!(!rejected.is_requested_execution());
1282 assert!(!rejected.is_substitution());
1283 assert!(rejected.is_rejected());
1284 }
1285
1286 fn base_model(model_id: u32, enabled: u8) -> KernelModel {
1287 KernelModel {
1288 model_id,
1289 provider_id: 0,
1290 quality_bps: 8_000,
1291 risk_ceiling_bps: 9_500,
1292 enabled,
1293 p95_latency_ms: 200,
1294 capabilities: 0,
1295 region_mask: ALL_REGIONS,
1296 input_cost_microunits_per_million_tokens: 100,
1297 output_cost_microunits_per_million_tokens: 400,
1298 }
1299 }
1300
1301 #[test]
1302 fn input_validate_rejects_out_of_range_bps() {
1303 let mut request = input();
1304 request.confidence_bps = 10_001;
1305 assert_eq!(
1306 request.validate(),
1307 Err(InputError::OutOfRangeBps {
1308 field: "confidence_bps",
1309 value: 10_001,
1310 max: MAX_BPS,
1311 })
1312 );
1313 }
1314
1315 #[test]
1316 fn input_validate_accepts_boundary_bps() {
1317 let mut request = input();
1318 request.risk_bps = MAX_BPS;
1319 request.confidence_bps = MAX_BPS;
1320 request.minimum_quality_bps = MAX_BPS;
1321 assert!(request.validate().is_ok());
1322 }
1323
1324 #[test]
1325 fn checked_prescribe_rejects_invalid_input_before_evaluation() {
1326 let snapshot = snapshot();
1327 let mut request = input();
1328 request.confidence_bps = MAX_BPS + 1;
1329 assert!(matches!(
1330 snapshot.prescribe_checked(request),
1331 Err(InputError::OutOfRangeBps {
1332 field: "confidence_bps",
1333 ..
1334 })
1335 ));
1336 assert!(snapshot.prescribe_with_trace_checked(request).is_err());
1337 assert!(snapshot
1338 .prescribe_batch_checked(&[input(), request])
1339 .is_err());
1340 }
1341
1342 #[test]
1343 fn policy_error_empty_catalog() {
1344 let snap = PolicySnapshot::new_unchecked(1, 1, 9_600, 5_500, 3_500, 0, vec![]);
1345 assert_eq!(snap.validate(), Err(PolicyError::EmptyCatalog));
1346 assert!(matches!(
1347 PolicySnapshot::try_new(1, 1, 9_600, 5_500, 3_500, 0, vec![]),
1348 Err(PolicyError::EmptyCatalog)
1349 ));
1350 }
1351
1352 #[test]
1353 fn policy_error_duplicate_model_id() {
1354 let snap = PolicySnapshot::new_unchecked(
1355 1,
1356 1,
1357 9_600,
1358 5_500,
1359 3_500,
1360 0,
1361 vec![base_model(1, 1), base_model(1, 1)],
1362 );
1363 assert_eq!(
1364 snap.validate(),
1365 Err(PolicyError::DuplicateModelId { model_id: 1 })
1366 );
1367 }
1368
1369 #[test]
1370 fn model_id_zero_is_reserved_for_rejection() {
1371 assert!(matches!(
1372 PolicySnapshot::try_new_trusted(1, 1, 9_600, 5_500, 3_500, 0, vec![base_model(0, 1)]),
1373 Err(TrustPolicyError::ReservedModelId)
1374 ));
1375 }
1376
1377 #[test]
1378 fn catalog_larger_than_decision_counters_is_rejected() {
1379 let models = (1..=u32::from(u16::MAX) + 1)
1380 .map(|model_id| base_model(model_id, 1))
1381 .collect();
1382 assert!(matches!(
1383 PolicySnapshot::try_new_trusted(1, 1, 9_600, 5_500, 3_500, 0, models),
1384 Err(TrustPolicyError::CatalogTooLarge { .. })
1385 ));
1386 }
1387
1388 #[test]
1389 fn policy_error_invalid_provider_id() {
1390 let mut model = base_model(1, 1);
1391 model.provider_id = MAX_PROVIDER_ID + 1;
1392 let snap = PolicySnapshot::new_unchecked(1, 1, 9_600, 5_500, 3_500, 0, vec![model]);
1393 assert_eq!(
1394 snap.validate(),
1395 Err(PolicyError::InvalidProviderId {
1396 model_id: 1,
1397 provider_id: MAX_PROVIDER_ID + 1,
1398 })
1399 );
1400 }
1401
1402 #[test]
1403 fn policy_error_no_enabled_models() {
1404 let snap = PolicySnapshot::new_unchecked(
1405 1,
1406 1,
1407 9_600,
1408 5_500,
1409 3_500,
1410 0,
1411 vec![base_model(1, 0), base_model(2, 0)],
1412 );
1413 assert_eq!(snap.validate(), Err(PolicyError::NoEnabledModels));
1414 }
1415
1416 #[test]
1417 fn policy_error_out_of_range_bps() {
1418 let models = vec![base_model(1, 1)];
1419 assert!(matches!(
1420 PolicySnapshot::try_new(1, 1, 10_001, 5_500, 3_500, 0, models.clone()),
1421 Err(PolicyError::OutOfRangeBps { .. })
1422 ));
1423 assert!(matches!(
1424 PolicySnapshot::try_new(1, 1, 9_600, 10_001, 3_500, 0, models.clone()),
1425 Err(PolicyError::OutOfRangeBps { .. })
1426 ));
1427 assert!(matches!(
1428 PolicySnapshot::try_new(1, 1, 9_600, 5_500, 50_001, 0, models.clone()),
1429 Err(PolicyError::OutOfRangeBps { .. })
1430 ));
1431 let mut bad_quality = base_model(2, 1);
1432 bad_quality.quality_bps = 10_001;
1433 assert!(matches!(
1434 PolicySnapshot::try_new(1, 1, 9_600, 5_500, 3_500, 0, vec![bad_quality]),
1435 Err(PolicyError::OutOfRangeBps { .. })
1436 ));
1437 }
1438
1439 #[test]
1440 fn utility_for_model_matches_eligible_catalog_entry() {
1441 let snap = snapshot();
1442 let input = input();
1443 let utility = snap.utility_for_model(input, 20);
1444 assert!(utility.is_some());
1445 assert_eq!(
1446 utility,
1447 Some(snap.prescribe(input).expected_utility_microunits)
1448 );
1449 }
1450
1451 #[test]
1452 fn utility_for_model_none_for_missing_id() {
1453 let snap = snapshot();
1454 assert!(snap.utility_for_model(input(), 999).is_none());
1455 }
1456
1457 #[test]
1458 fn prescribe_batch_matches_individual() {
1459 let snap = snapshot();
1460 let inputs = [
1461 input(),
1462 KernelInput {
1463 request_sequence: 2,
1464 requested_model_id: 10,
1465 input_tokens: 500,
1466 output_tokens: 100,
1467 business_value_microunits: 50_000_000,
1468 budget_limit_microunits: 5_000_000,
1469 risk_bps: 500,
1470 confidence_bps: 9_500,
1471 minimum_quality_bps: 7_000,
1472 max_p95_latency_ms: 500,
1473 required_capabilities: TOOLS,
1474 allowed_provider_mask: ALL_PROVIDERS,
1475 required_region_mask: REGION_EU,
1476 },
1477 ];
1478 let batch = snap.prescribe_batch(&inputs);
1479 assert_eq!(batch.len(), inputs.len());
1480 for (i, &inp) in inputs.iter().enumerate() {
1481 assert_eq!(batch[i], snap.prescribe(inp));
1482 }
1483 }
1484
1485 #[test]
1486 fn hard_constraints_fail_closed() {
1487 let mut request = input();
1488 request.risk_bps = 9_900;
1489 let decision = snapshot().prescribe(request);
1490 assert_eq!(decision.action, KernelAction::Reject);
1491 assert_eq!(decision.reason, KernelReason::RiskHardLimit);
1492
1493 request.risk_bps = 1_000;
1494 request.required_capabilities = 1 << 9;
1495 let decision = snapshot().prescribe(request);
1496 assert_eq!(decision.action, KernelAction::Reject);
1497 assert_eq!(decision.reason, KernelReason::CapabilityConstraint);
1498 }
1499
1500 #[test]
1501 fn extreme_inputs_saturate_without_panicking() {
1502 let mut request = input();
1503 request.input_tokens = u32::MAX;
1504 request.output_tokens = u32::MAX;
1505 request.business_value_microunits = i64::MAX;
1506 request.budget_limit_microunits = u64::MAX;
1507 let decision = snapshot().prescribe(request);
1508 assert_eq!(decision.request_sequence, request.request_sequence);
1509 }
1510
1511 #[test]
1512 fn exact_fast_path_preserves_single_rounding_step() {
1513 assert_eq!(scaled_term_reference(2, 5_001, 9_999), 1);
1514 assert_eq!(scaled_term_exact(2, 5_001, 9_999), 1);
1515 }
1516
1517 proptest! {
1518 #[test]
1519 fn optimized_scaled_term_matches_i128_reference(
1520 value in any::<u64>(),
1521 first_bps in any::<u16>(),
1522 second_bps in any::<u16>(),
1523 ) {
1524 prop_assert_eq!(
1525 scaled_term_exact(value, u64::from(first_bps), u64::from(second_bps)),
1526 scaled_term_reference(value, u64::from(first_bps), u64::from(second_bps)),
1527 );
1528 }
1529
1530 #[test]
1531 fn optimized_cost_matches_u128_reference_when_guard_admits(
1532 input_tokens in any::<u32>(),
1533 output_tokens in any::<u32>(),
1534 input_price in any::<u64>(),
1535 output_price in any::<u64>(),
1536 ) {
1537 let model = KernelModel {
1538 model_id: 1,
1539 provider_id: 0,
1540 quality_bps: 10_000,
1541 risk_ceiling_bps: u16::MAX,
1542 enabled: 1,
1543 p95_latency_ms: 1,
1544 capabilities: 0,
1545 region_mask: ALL_REGIONS,
1546 input_cost_microunits_per_million_tokens: input_price,
1547 output_cost_microunits_per_million_tokens: output_price,
1548 };
1549 let snapshot = PolicySnapshot::new_unchecked(1, 1, u16::MAX, 0, 0, 0, vec![model]);
1550 if snapshot.all_costs_fit_u64(input_tokens, output_tokens) {
1551 prop_assert_eq!(
1552 model_cost_fast(&model, input_tokens, output_tokens),
1553 model_cost_reference(&model, input_tokens, output_tokens),
1554 );
1555 }
1556 }
1557
1558 #[test]
1559 fn optimized_kernel_matches_reference_decision(
1560 input_tokens in any::<u32>(),
1561 output_tokens in any::<u32>(),
1562 value in any::<i64>(),
1563 budget in any::<u64>(),
1564 risk in any::<u16>(),
1565 confidence in any::<u16>(),
1566 minimum_quality in any::<u16>(),
1567 maximum_latency in any::<u32>(),
1568 provider_mask in any::<u64>(),
1569 region_mask in any::<u64>(),
1570 ) {
1571 let mut request = input();
1572 request.input_tokens = input_tokens;
1573 request.output_tokens = output_tokens;
1574 request.business_value_microunits = value;
1575 request.budget_limit_microunits = budget;
1576 request.risk_bps = risk;
1577 request.confidence_bps = confidence;
1578 request.minimum_quality_bps = minimum_quality;
1579 request.max_p95_latency_ms = maximum_latency;
1580 request.allowed_provider_mask = provider_mask;
1581 request.required_region_mask = region_mask;
1582 let snapshot = snapshot();
1583 prop_assert_eq!(snapshot.prescribe(request), prescribe_reference(&snapshot, request));
1584 }
1585
1586 #[test]
1587 fn arbitrary_inputs_never_bypass_provider_fence(
1588 input_tokens in any::<u32>(),
1589 output_tokens in any::<u32>(),
1590 value in any::<i64>(),
1591 budget in any::<u64>(),
1592 risk in any::<u16>(),
1593 confidence in any::<u16>(),
1594 ) {
1595 let mut request = input();
1596 request.input_tokens = input_tokens;
1597 request.output_tokens = output_tokens;
1598 request.business_value_microunits = value;
1599 request.budget_limit_microunits = budget;
1600 request.risk_bps = risk;
1601 request.confidence_bps = confidence;
1602 request.allowed_provider_mask = 0;
1603 let decision = snapshot().prescribe(request);
1604 prop_assert_eq!(decision.action, KernelAction::Reject);
1605 }
1606 }
1607
1608 #[test]
1609 fn provider_id_above_64_rejected_even_with_all_providers() {
1610 let models = vec![KernelModel {
1611 model_id: 1,
1612 provider_id: 65,
1613 quality_bps: 9500,
1614 risk_ceiling_bps: 10000,
1615 enabled: 1,
1616 p95_latency_ms: 500,
1617 capabilities: 0,
1618 region_mask: ALL_REGIONS,
1619 input_cost_microunits_per_million_tokens: 100,
1620 output_cost_microunits_per_million_tokens: 400,
1621 }];
1622 let snapshot = PolicySnapshot::new_unchecked(1, 1, 9600, 5500, 3500, 0, models);
1623 let mut request = input();
1624 request.allowed_provider_mask = ALL_PROVIDERS;
1625 let decision = snapshot.prescribe(request);
1626 assert_eq!(
1627 decision.action,
1628 KernelAction::Reject,
1629 "provider_id >= 64 must be rejected even when mask is ALL_PROVIDERS"
1630 );
1631 }
1632
1633 #[test]
1634 fn provider_id_below_64_accepted_with_all_providers() {
1635 let mut request = input();
1636 request.allowed_provider_mask = ALL_PROVIDERS;
1637 let decision = snapshot().prescribe(request);
1638 assert_ne!(
1639 decision.action,
1640 KernelAction::Reject,
1641 "provider_id < 64 with ALL_PROVIDERS should not be rejected by provider fence"
1642 );
1643 }
1644
1645 #[test]
1646 #[ignore = "release-only kernel guard"]
1647 fn prescriptive_kernel_latency_guard() {
1648 let snapshot = snapshot();
1649 let base = input();
1650 let iterations = 1_000_000_u64;
1651 let started = Instant::now();
1652 for sequence in 0..iterations {
1653 let mut request = base;
1654 request.request_sequence = sequence;
1655 request.input_tokens = 1_000 + (sequence % 1_024) as u32;
1656 black_box(snapshot.prescribe(black_box(request)));
1657 }
1658 let average_ns = started.elapsed().as_nanos() / u128::from(iterations);
1659 assert!(
1660 average_ns < 2_000,
1661 "prescriptive kernel exceeded 2us average guard: {average_ns}ns"
1662 );
1663 }
1664}