refactor(proofs): split into per-topic modules with shared helpers across types, domain, and kernel

This commit is contained in:
2026-10-18 01:08:05 +02:00
parent e5fd6372b3
commit 71518a93a4
16 changed files with 554 additions and 607 deletions

View File

@@ -1,83 +0,0 @@
#[cfg(kani)]
mod kani_proofs {
use crate::bounded::{CapSlot, PageCount, Priority};
use crate::generation::Generation;
use crate::permission::PermissionSet;
#[kani::proof]
fn restrict_to_never_escalates() {
let a: u8 = kani::any();
let b: u8 = kani::any();
let original = PermissionSet::from_bits(a);
let restrictor = PermissionSet::from_bits(b);
let result = original.restrict_to(&restrictor);
assert!(result.is_subset_of(&original));
assert!(result.is_subset_of(&restrictor));
}
#[kani::proof]
fn restrict_to_is_commutative_in_result() {
let a: u8 = kani::any();
let b: u8 = kani::any();
let set_a = PermissionSet::from_bits(a);
let set_b = PermissionSet::from_bits(b);
let ab = set_a.restrict_to(&set_b);
let ba = set_b.restrict_to(&set_a);
assert!(ab == ba);
}
#[kani::proof]
fn empty_permission_set_restricts_everything_to_empty() {
let a: u8 = kani::any();
let set = PermissionSet::from_bits(a);
let empty = PermissionSet::empty();
let result = set.restrict_to(&empty);
assert!(result == empty);
}
#[kani::proof]
fn generation_next_always_invalidates() {
let value: u32 = kani::any();
let current = Generation::from_raw(value);
let next = current.next();
assert!(!current.is_valid_against(&next));
}
#[kani::proof]
fn capslot_always_valid_index() {
let value: u8 = kani::any();
if let Some(slot) = CapSlot::new(value) {
assert!(slot.value() <= 63);
}
}
#[kani::proof]
fn capslot_rejects_out_of_range() {
let value: u8 = kani::any();
kani::assume(value > 63);
assert!(CapSlot::new(value).is_none());
}
#[kani::proof]
fn priority_always_fits_in_bitmap() {
let value: u8 = kani::any();
if let Some(prio) = Priority::new(value) {
assert!((prio.value() as u32) < 32);
}
}
#[kani::proof]
fn page_count_is_always_nonzero() {
let value: u16 = kani::any();
if let Some(count) = PageCount::new(value) {
assert!(count.value() >= 1);
}
}
}

View File

@@ -0,0 +1,32 @@
use crate::bounded::{CapSlot, PageCount, Priority};
#[kani::proof]
fn capslot_always_valid_index() {
let value: u8 = kani::any();
if let Some(slot) = CapSlot::new(value) {
assert!(slot.value() <= 63);
}
}
#[kani::proof]
fn capslot_rejects_out_of_range() {
let value: u8 = kani::any();
kani::assume(value > 63);
assert!(CapSlot::new(value).is_none());
}
#[kani::proof]
fn priority_always_fits_in_bitmap() {
let value: u8 = kani::any();
if let Some(prio) = Priority::new(value) {
assert!((prio.value() as u32) < 32);
}
}
#[kani::proof]
fn page_count_is_always_nonzero() {
let value: u16 = kani::any();
if let Some(count) = PageCount::new(value) {
assert!(count.value() >= 1);
}
}

View File

@@ -0,0 +1,10 @@
use crate::generation::Generation;
#[kani::proof]
fn generation_next_always_invalidates() {
let value: u32 = kani::any();
let current = Generation::from_raw(value);
let next = current.next();
assert!(!current.is_valid_against(&next));
}

View File

@@ -0,0 +1,3 @@
mod bounded;
mod generation;
mod permissions;

View File

@@ -0,0 +1,38 @@
use crate::permission::PermissionSet;
#[kani::proof]
fn restrict_to_never_escalates() {
let a: u8 = kani::any();
let b: u8 = kani::any();
let original = PermissionSet::from_bits(a);
let restrictor = PermissionSet::from_bits(b);
let result = original.restrict_to(&restrictor);
assert!(result.is_subset_of(&original));
assert!(result.is_subset_of(&restrictor));
}
#[kani::proof]
fn restrict_to_is_commutative_in_result() {
let a: u8 = kani::any();
let b: u8 = kani::any();
let set_a = PermissionSet::from_bits(a);
let set_b = PermissionSet::from_bits(b);
let ab = set_a.restrict_to(&set_b);
let ba = set_b.restrict_to(&set_a);
assert!(ab == ba);
}
#[kani::proof]
fn empty_permission_set_restricts_everything_to_empty() {
let a: u8 = kani::any();
let set = PermissionSet::from_bits(a);
let empty = PermissionSet::empty();
let result = set.restrict_to(&empty);
assert!(result == empty);
}