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 | "budget_usage_reported"
79 | "checkpoint_taken"
80 | "rollbacked"
81 | "milestone_advanced"
82 | "milestone_blocked" => KernelEventCategory::Sched,
83 "compressed"
84 | "page_out"
85 | "page_in"
86 | "renewed"
87 | "context_renewed"
88 | "large_result_spooled" => KernelEventCategory::Mm,
89 "agent_process_changed"
90 | "agent_spawned"
91 | "workflow_batch_spawned"
92 | "workflow_completed"
93 | "agent_preempted" => KernelEventCategory::Proc,
94 "signal_delivery_disposed" => KernelEventCategory::Ipc,
95 "memory_written" | "memory_queried" | "memory_validation_failed" => KernelEventCategory::Mm,
96 _ => KernelEventCategory::Sched,
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn maps_observation_kinds_to_categories() {
106 assert_eq!(
107 category_for_kind("tool_gated"),
108 KernelEventCategory::Syscall
109 );
110 assert_eq!(category_for_kind("page_out"), KernelEventCategory::Mm);
111 assert_eq!(
112 category_for_kind("agent_process_changed"),
113 KernelEventCategory::Proc
114 );
115 assert_eq!(
116 category_for_kind("signal_delivery_disposed"),
117 KernelEventCategory::Ipc
118 );
119 assert_eq!(category_for_kind("suspended"), KernelEventCategory::Sched);
120 }
121
122 #[test]
123 fn categories_roll_up_to_three_primitives() {
124 assert_eq!(KernelEventCategory::Syscall.primitive(), Primitive::Syscall);
126 assert_eq!(KernelEventCategory::Sched.primitive(), Primitive::Sched);
127 assert_eq!(KernelEventCategory::Proc.primitive(), Primitive::Sched);
128 assert_eq!(KernelEventCategory::Ipc.primitive(), Primitive::Sched);
129 assert_eq!(KernelEventCategory::Mm.primitive(), Primitive::Mm);
130 }
131
132 #[test]
133 fn every_kernel_observation_kind_maps_to_a_primitive() {
134 assert_eq!(
136 primitive_for_kind("agent_process_changed"),
137 Primitive::Sched
138 );
139 assert_eq!(
140 primitive_for_kind("signal_delivery_disposed"),
141 Primitive::Sched
142 );
143 assert_eq!(primitive_for_kind("tool_gated"), Primitive::Syscall);
144 assert_eq!(primitive_for_kind("page_out"), Primitive::Mm);
145 }
146}