wire/privacy.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//! The privacy page's vocabulary (`crates/wire/spec/Privacy.lean`): the
7//! closed sets every control is described by (§8-87), the answer to
8//! `Query::Privacy` (§8-88) and the operation `Command::PrivacyOperation`
9//! carries (§8-89).
10//!
11//! **The host's table is the one authority.** A control's target path, the
12//! value it writes and its edition lists are defined once, in the binary's
13//! `privacy::controls`, and reach the page only inside the answer; the
14//! words the page shows are defined once, in the client's `lang.json`,
15//! keyed by the spellings of these sets. Each set therefore has exactly
16//! one list of members, and every reader takes it from here.
17
18mod answer;
19mod operation;
20
21pub use answer::{PrivacyAnswer, PrivacyControlEntry, PrivacyCurrent, PrivacyEditions};
22pub use answer::{PrivacyHistory, PrivacyHost, PrivacyIntent, PrivacyNotWrittenEntry};
23pub use answer::{PrivacyOriginalLine, PrivacyTarget, PrivacyValue, PrivacyWindows};
24pub use operation::{PrivacyAction, PrivacyOutcome, PrivacyRequest, PrivacyResult};
25
26use serde::{Deserialize, Serialize};
27
28/// Declares a closed set together with `ALL`, its members in declaration
29/// order. The array is the variant list itself, so a member cannot be
30/// added to the enum and left out of the order the page draws in.
31macro_rules! listed {
32 (
33 $(#[$attr:meta])*
34 pub enum $name:ident { $($(#[$member:meta])* $variant:ident),* $(,)? }
35 ) => {
36 $(#[$attr])*
37 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
38 #[serde(rename_all = "snake_case")]
39 #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
40 pub enum $name { $($(#[$member])* $variant),* }
41
42 impl $name {
43 /// Every member, in the order the privacy page shows them.
44 pub const ALL: [Self; [$(stringify!($variant)),*].len()] = [$(Self::$variant),*];
45 }
46 };
47}
48
49listed! {
50 /// One host setting this binary may change for the person on request
51 /// (a privacy control). Declared in page order: by
52 /// [`PrivacyCategory`], and within a category in the order of the
53 /// controls table.
54 pub enum PrivacyControl {
55 // Diagnostics and telemetry.
56 PowershellTelemetryOptout,
57 CeipConsolidatorTask,
58 CeipUsbTask,
59 WindowsCeip,
60 DiagnosticData,
61 FeedbackNotifications,
62 StepsRecorder,
63 ErrorReporting,
64 ErrorReportingAdditionalData,
65 DiagnosticLogCollection,
66 DumpCollection,
67 ApplicationTelemetry,
68 DeviceCensusTask,
69 DeviceCensusUserTask,
70 DotnetCliTelemetryOptout,
71 // Speech, typing and inking.
72 VoiceActivation,
73 VoiceActivationAboveLock,
74 OnlineSpeechRecognition,
75 ImplicitTextCollection,
76 ImplicitInkCollection,
77 HandwritingErrorReports,
78 InputPersonalization,
79 LinguisticDataCollection,
80 HandwritingDataSharing,
81 // Location and sensors.
82 LocationProvider,
83 LocationFeature,
84 Sensors,
85 // Search.
86 SearchWeb,
87 SearchWebResults,
88 CloudSearch,
89 Cortana,
90 CortanaAboveLock,
91 SearchLocation,
92 SearchHighlights,
93 // Suggestions, advertising and cloud content.
94 TailoredExperiences,
95 Spotlight,
96 ConsumerFeatures,
97 CloudOptimizedContent,
98 WindowsTips,
99 ConsumerAccountStateContent,
100 ThirdPartySuggestions,
101 SettingsOnlineTips,
102 Widgets,
103 AdvertisingId,
104 LanguageListWebsites,
105 // Activity history and cross-device.
106 StartLaunchTracking,
107 ActivityFeed,
108 ActivityPublish,
109 ActivityUpload,
110 ClipboardHistory,
111 CloudClipboard,
112 ContinueExperiences,
113 PhonePcLinking,
114 MessageSync,
115 // Cloud services and network connections.
116 OnesettingsDownloads,
117 FindMyDevice,
118 DeliveryOptimization,
119 OnedriveFileStorage,
120 OnedrivePreSigninTraffic,
121 PushNotificationsNetwork,
122 // App permissions.
123 AppLocation,
124 AppAccountInfo,
125 AppMotion,
126 AppPhoneCalls,
127 AppTrustedDevices,
128 AppUnpairedDevices,
129 AppDiagnosticInfo,
130 AppContacts,
131 AppCalendar,
132 AppCallHistory,
133 AppEmail,
134 AppTasks,
135 AppMessaging,
136 AppRadios,
137 AppCamera,
138 AppMicrophone,
139 AppNotifications,
140 AppBackground,
141 AppScreenCaptureProgrammatic,
142 AppScreenCaptureBorderless,
143 AppGazeInput,
144 AppHumanPresence,
145 AppForegroundText,
146 CameraDevice,
147 // Windows AI.
148 AppSystemAiModels,
149 RecallSnapshots,
150 RecallComponent,
151 ClickToDo,
152 }
153}
154
155listed! {
156 /// One line of the privacy request list as the person wrote it (an
157 /// original item), numbered as the list numbers it.
158 pub enum PrivacyOriginal {
159 K01,
160 K02,
161 K03,
162 K04,
163 K05,
164 K06,
165 K07,
166 K08,
167 K09,
168 K10,
169 K11,
170 K12,
171 K13,
172 K14,
173 K15,
174 K16,
175 K17,
176 K18,
177 K19,
178 K20,
179 K21,
180 K22,
181 K23,
182 K24,
183 K25,
184 K26,
185 K27,
186 K28,
187 K29,
188 K30,
189 K31,
190 K32,
191 K33,
192 K34,
193 K35,
194 K36,
195 K37,
196 K38,
197 K39,
198 K40,
199 K41,
200 K42,
201 K43,
202 K44,
203 K45,
204 K46,
205 K47,
206 K48,
207 K49,
208 K50,
209 K51,
210 K52,
211 }
212}
213
214listed! {
215 /// Why an original item is not written. The research decided each
216 /// one; nothing here is a judgement the host makes at run time.
217 pub enum PrivacyNotWritten {
218 /// No current policy template or policy CSP has the target.
219 Absent,
220 /// The target exists and Microsoft has retired what it governs.
221 Obsolete,
222 /// The sources do not settle the target's type or written value.
223 Undeterminable,
224 /// Writing it needs an operation kind this version does not have.
225 NeedsOperationKind,
226 }
227}
228
229listed! {
230 /// The sections of the privacy page, in page order.
231 pub enum PrivacyCategory {
232 Diagnostics,
233 SpeechInput,
234 LocationSensors,
235 Search,
236 Content,
237 ActivitySync,
238 CloudServices,
239 AppPermissions,
240 WindowsAi,
241 }
242}
243
244listed! {
245 /// The Windows editions Microsoft's documentation names when it says
246 /// where a policy is honoured or ignored.
247 pub enum PrivacyEdition {
248 Home,
249 Pro,
250 Enterprise,
251 Education,
252 IotEnterprise,
253 Server,
254 }
255}
256
257listed! {
258 /// What the sources say about whether writing a control changes
259 /// anything on current Windows builds.
260 pub enum PrivacyBuildEffect {
261 /// The effect is documented for current builds.
262 Documented,
263 /// The setting exists, and the sources leave open whether current
264 /// builds still act on it.
265 Uncertain,
266 /// The service or feature it governs has ended; writing it changes
267 /// nothing today.
268 NoCurrentEffect,
269 }
270}
271
272listed! {
273 /// How a control's edition lists read for the edition of this host.
274 pub enum PrivacyEditionFit {
275 /// The host's edition is in the control's honoured list.
276 Honoured,
277 /// The host's edition is in the control's ignored list.
278 Ignored,
279 /// Neither list names the host's edition, or the host's edition is
280 /// not one of [`PrivacyEdition`].
281 NotStated,
282 }
283}
284
285listed! {
286 /// Whose settings a control changes. A machine-scope write goes
287 /// through administrator approval.
288 pub enum PrivacyScope {
289 User,
290 Machine,
291 }
292}
293
294listed! {
295 /// The person's check of an operation that has no conclusion. It
296 /// writes nothing; it records what the target held.
297 pub enum PrivacySettlement {
298 /// The target held the operation's modified value: an apply now
299 /// owns its change.
300 Applied,
301 /// The target held the operation's original value.
302 NotApplied,
303 /// The target held a restore's modified value: the change it
304 /// undid is no longer owned.
305 Restored,
306 /// The target held neither value; nothing is owned and nothing is
307 /// put back.
308 Abandoned,
309 }
310}
311
312listed! {
313 /// Why a privacy operation ended without the change asked for, or
314 /// with a result nobody could confirm: the closed set of stable codes
315 /// (`crates/sprawling/spec/Privacy.lean` §12).
316 pub enum PrivacyFaultCode {
317 Identity,
318 Clock,
319 History,
320 Unreadable,
321 Unresolved,
322 Changed,
323 TargetAbsent,
324 NothingOwned,
325 Conflict,
326 NothingUnresolved,
327 HistoryFull,
328 Expired,
329 AccessDenied,
330 ElevationDeclined,
331 NotApplied,
332 ReadbackMismatch,
333 Unknown,
334 ReceiptLost,
335 }
336}
337
338impl PrivacyFaultCode {
339 /// The code as it travels, which every privacy error's subject also
340 /// opens with.
341 pub const fn as_str(self) -> &'static str {
342 match self {
343 Self::Identity => "identity",
344 Self::Clock => "clock",
345 Self::History => "history",
346 Self::Unreadable => "unreadable",
347 Self::Unresolved => "unresolved",
348 Self::Changed => "changed",
349 Self::TargetAbsent => "target_absent",
350 Self::NothingOwned => "nothing_owned",
351 Self::Conflict => "conflict",
352 Self::NothingUnresolved => "nothing_unresolved",
353 Self::HistoryFull => "history_full",
354 Self::Expired => "expired",
355 Self::AccessDenied => "access_denied",
356 Self::ElevationDeclined => "elevation_declined",
357 Self::NotApplied => "not_applied",
358 Self::ReadbackMismatch => "readback_mismatch",
359 Self::Unknown => "unknown",
360 Self::ReceiptLost => "receipt_lost",
361 }
362 }
363}
364
365#[cfg(test)]
366#[allow(clippy::unwrap_used, reason = "test code")]
367mod tests {
368 use super::PrivacyFaultCode;
369
370 /// The subject prefix and the wire spelling are one spelling.
371 #[test]
372 fn a_fault_code_reads_as_it_travels() {
373 for code in PrivacyFaultCode::ALL {
374 assert_eq!(
375 serde_json::to_value(code).unwrap(),
376 serde_json::Value::from(code.as_str())
377 );
378 }
379 }
380}