kernel/event/record/control.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4// Copyright (c) 2026 2youg1 and the sprawling contributors
5
6//! What the city records about its own founding, about a run being
7//! stopped or handed on, and about the governance lines no writer
8//! records yet.
9//!
10//! Three kinds of this family carry a type that lives elsewhere, and
11//! the struct is that type rather than a copy of it: `gate_denied` and
12//! `budget_limit` carry an [`AxError`](crate::AxError) laid flat, the
13//! carrier table in `kernel::error` being the authority on which code
14//! lands under which kind; `approval_requested` carries an
15//! [`ApprovalItem`](crate::ApprovalItem). `result_offloaded` stays with
16//! `runtime::sieve`, whose account it flattens in.
17
18use serde::{Deserialize, Serialize};
19
20use crate::address::Address;
21use crate::locator::Locator;
22
23/// `city_initialized`: the first line of every history. The city's name
24/// is the record's own `addr`, so the payload holds nothing.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
26#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
27pub struct CityInitialized {}
28
29/// `building_created`: a building now stands at `addr`, laid out from
30/// `template`, or found already standing when `adopted`.
31#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
32#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
33pub struct BuildingCreated {
34 #[cfg_attr(feature = "schema", schemars(with = "String"))]
35 pub addr: Address,
36 /// The template's own name, as `city::BuildingTemplate::name`
37 /// spells it.
38 pub template: String,
39 /// Written only on an adoption, as the hand-written writer left it.
40 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
41 pub adopted: bool,
42}
43
44/// `building_configured`: which faces of a building's own layer one
45/// reconfiguration wrote. The values themselves stay in the files.
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
48pub struct BuildingConfigured {
49 #[cfg_attr(feature = "schema", schemars(with = "String"))]
50 pub addr: Address,
51 pub sandbox: bool,
52 pub mcp: bool,
53 pub desktop: bool,
54 pub context: bool,
55}
56
57/// `cancel_received`: the turn saw the stop. The run it belongs to is
58/// the envelope's, so the payload holds nothing.
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
60#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
61pub struct CancelReceived {}
62
63/// `handoff_written`: the five sections a successor starts from.
64///
65/// `runtime::handoff::Handoff` is the only way to hold a valid one; this
66/// is what it writes, so its refusal of an empty must-read list is not
67/// re-checked by a reader.
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
69#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
70pub struct HandoffWritten {
71 #[cfg_attr(feature = "schema", schemars(with = "Vec<String>"))]
72 pub must_read: Vec<Locator>,
73 pub overview: String,
74 pub progress: String,
75 pub context: String,
76 pub next_step: String,
77}
78
79/// `watchdog_fired`: what the watchdog did, and how often it has had to.
80#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
81#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
82pub struct WatchdogFired {
83 #[serde(flatten)]
84 pub action: FiredAction,
85 /// How many corrective steers this run has been given.
86 pub corrections: u32,
87 /// How many provider failures this run has met.
88 pub provider_failures: u32,
89}
90
91/// What the watchdog did, in the word the line carries.
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
93#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
94#[serde(tag = "action", rename_all = "snake_case")]
95pub enum FiredAction {
96 /// The model was told it is repeating itself.
97 Steer { text: String },
98 /// The same call will be made again, no earlier than `until_ms`,
99 /// because of the failure whose stable code and subject are named
100 /// here.
101 BackOff {
102 until_ms: u64,
103 code: String,
104 subject: String,
105 },
106 /// The same call goes out at once on another account of the
107 /// provider, because of the failure whose stable code and subject are
108 /// named here (`crates/kernel/spec/AccountRecovery.lean` ยง8-86).
109 Switch {
110 to: crate::ServerLabel,
111 code: String,
112 subject: String,
113 },
114 /// The run was frozen.
115 Freeze { reason: String },
116}
117
118/// `gate_checked`: a gate let an action through.
119///
120/// No production line records this kind, so no bytes fix its shape; the
121/// struct is empty by decision, because the action it admitted is the
122/// next line of the same run and a copy here would be a second spelling
123/// of it.
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
125#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
126pub struct GateChecked {}
127
128/// `policy_created` and `policy_revoked`: a standing rule named `id`
129/// came into force or left it.
130///
131/// No line records either kind yet, so no bytes fix the shape. The
132/// struct holds the rule's name alone by decision: the rule's text is a
133/// governed document, which `governed_document_written` already records,
134/// and a copy here would be its second authority.
135#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
136#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
137pub struct PolicyChanged {
138 pub id: String,
139}
140
141#[cfg(test)]
142#[allow(
143 clippy::unwrap_used,
144 clippy::expect_used,
145 clippy::panic,
146 clippy::indexing_slicing,
147 reason = "test code"
148)]
149mod tests;