Skip to main content

qualia_core_db/entity_view/
circumstance.rs

1//! Circumstance tuple (role, audience, quorum, environment, evaluatory).
2//!
3//! Partial host surface: serializable descriptor for design + session hooks.
4//! Full path-steering (job vs private, cafe vs Sanctuary) is host composition.
5
6use serde::{Deserialize, Serialize};
7
8/// Coarse place / environment type for presentation steering.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
10#[serde(rename_all = "snake_case")]
11#[repr(u8)]
12pub enum EnvironmentKind {
13    #[default]
14    Unspecified = 0,
15    PrivateSanctuary = 1,
16    Workplace = 2,
17    PublicCafe = 3,
18    ClinicalCare = 4,
19    Education = 5,
20    FieldMobile = 6,
21}
22
23/// Evaluatory priority axis (what the principal is optimising for now).
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
25#[serde(rename_all = "snake_case")]
26#[repr(u8)]
27pub enum EvaluatoryFocus {
28    #[default]
29    Open = 0,
30    CareSafety = 1,
31    WorkDelivery = 2,
32    Learning = 3,
33    SocialCommons = 4,
34    LegalProcess = 5,
35}
36
37/// Spatio-social-temporal circumstance for one attention session.
38///
39/// Pure data - does not enforce rights (see `rights_filter` + deontic).
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
41pub struct Circumstance {
42    /// Social / organisational role label (employee, parent, patient) - free text cold path.
43    pub role: String,
44    /// Audience class (self, peer_dyad, team, public, court).
45    pub audience: String,
46    /// Required quorum of parties (1 = solo; 2+ multi-party consent).
47    pub quorum: u8,
48    pub environment: EnvironmentKind,
49    pub evaluatory: EvaluatoryFocus,
50    /// Optional place/label hash carrier (0 = unset); hosts may set from geo/library place.
51    pub place_hint: u64,
52}
53
54impl Circumstance {
55    pub fn private_sanctuary() -> Self {
56        Self {
57            role: "principal".into(),
58            audience: "self".into(),
59            quorum: 1,
60            environment: EnvironmentKind::PrivateSanctuary,
61            evaluatory: EvaluatoryFocus::Open,
62            place_hint: 0,
63        }
64    }
65
66    pub fn workplace_employee() -> Self {
67        Self {
68            role: "employee".into(),
69            audience: "employer_org".into(),
70            quorum: 1,
71            environment: EnvironmentKind::Workplace,
72            evaluatory: EvaluatoryFocus::WorkDelivery,
73            place_hint: 0,
74        }
75    }
76
77    /// Whether this circumstance should bias representation away from private wing UI chrome.
78    pub fn prefers_reduced_private_chrome(&self) -> bool {
79        matches!(
80            self.environment,
81            EnvironmentKind::Workplace | EnvironmentKind::PublicCafe
82        ) || self.audience == "employer_org"
83            || self.audience == "public"
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn workplace_prefers_reduced_private() {
93        let c = Circumstance::workplace_employee();
94        assert!(c.prefers_reduced_private_chrome());
95        assert!(!Circumstance::private_sanctuary().prefers_reduced_private_chrome());
96    }
97}