Skip to main content

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 run was frozen.
107    Freeze { reason: String },
108}
109
110/// `gate_checked`: a gate let an action through.
111///
112/// No production line records this kind, so no bytes fix its shape; the
113/// struct is empty by decision, because the action it admitted is the
114/// next line of the same run and a copy here would be a second spelling
115/// of it.
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
117#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
118pub struct GateChecked {}
119
120/// `policy_created` and `policy_revoked`: a standing rule named `id`
121/// came into force or left it.
122///
123/// No line records either kind yet, so no bytes fix the shape. The
124/// struct holds the rule's name alone by decision: the rule's text is a
125/// governed document, which `governed_document_written` already records,
126/// and a copy here would be its second authority.
127#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
128#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
129pub struct PolicyChanged {
130    pub id: String,
131}
132
133#[cfg(test)]
134#[allow(
135    clippy::unwrap_used,
136    clippy::expect_used,
137    clippy::panic,
138    clippy::indexing_slicing,
139    reason = "test code"
140)]
141mod tests;