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