deepstrike_core/runtime/
event_log.rs1use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum Primitive {
19 Syscall,
21 Sched,
23 Mm,
25}
26
27impl Primitive {
28 pub fn label(self) -> &'static str {
29 match self {
30 Self::Syscall => "syscall",
31 Self::Sched => "sched",
32 Self::Mm => "mm",
33 }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
40#[serde(rename_all = "snake_case")]
41pub enum KernelEventCategory {
42 Syscall,
44 Sched,
46 Mm,
48 Proc,
50 Ipc,
52}
53
54impl KernelEventCategory {
55 pub fn primitive(self) -> Primitive {
58 match self {
59 Self::Syscall => Primitive::Syscall,
60 Self::Sched | Self::Proc | Self::Ipc => Primitive::Sched,
61 Self::Mm => Primitive::Mm,
62 }
63 }
64}
65
66pub fn primitive_for_kind(kind: &str) -> Primitive {
68 category_for_kind(kind).primitive()
69}
70
71pub fn category_for_kind(kind: &str) -> KernelEventCategory {
73 match kind {
74 "tool_gated" | "capability_changed" => KernelEventCategory::Syscall,
75 "suspended"
76 | "resumed"
77 | "budget_exceeded"
78 | "checkpoint_taken"
79 | "rollbacked"
80 | "milestone_advanced"
81 | "milestone_blocked" => KernelEventCategory::Sched,
82 "compressed"
83 | "page_out"
84 | "page_in"
85 | "renewed"
86 | "context_renewed"
87 | "large_result_spooled" => KernelEventCategory::Mm,
88 "agent_process_changed" | "agent_spawned" | "workflow_batch_spawned"
89 | "workflow_completed" | "agent_preempted" => KernelEventCategory::Proc,
90 "signal_disposed" => KernelEventCategory::Ipc,
91 "memory_written" | "memory_queried" | "memory_validation_failed" => KernelEventCategory::Mm,
92 _ => KernelEventCategory::Sched,
93 }
94}
95
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn maps_observation_kinds_to_categories() {
103 assert_eq!(category_for_kind("tool_gated"), KernelEventCategory::Syscall);
104 assert_eq!(category_for_kind("page_out"), KernelEventCategory::Mm);
105 assert_eq!(category_for_kind("agent_process_changed"), KernelEventCategory::Proc);
106 assert_eq!(category_for_kind("signal_disposed"), KernelEventCategory::Ipc);
107 assert_eq!(category_for_kind("suspended"), KernelEventCategory::Sched);
108 }
109
110 #[test]
111 fn categories_roll_up_to_three_primitives() {
112 assert_eq!(KernelEventCategory::Syscall.primitive(), Primitive::Syscall);
114 assert_eq!(KernelEventCategory::Sched.primitive(), Primitive::Sched);
115 assert_eq!(KernelEventCategory::Proc.primitive(), Primitive::Sched);
116 assert_eq!(KernelEventCategory::Ipc.primitive(), Primitive::Sched);
117 assert_eq!(KernelEventCategory::Mm.primitive(), Primitive::Mm);
118 }
119
120 #[test]
121 fn every_kernel_observation_kind_maps_to_a_primitive() {
122 assert_eq!(primitive_for_kind("agent_process_changed"), Primitive::Sched);
124 assert_eq!(primitive_for_kind("signal_disposed"), Primitive::Sched);
125 assert_eq!(primitive_for_kind("tool_gated"), Primitive::Syscall);
126 assert_eq!(primitive_for_kind("page_out"), Primitive::Mm);
127 }
128}