Skip to main content

qualia_core_db/governance/webizen/
agreement.rs

1use super::*;
2
3#[cfg(feature = "alloc_buffers")]
4extern crate alloc;
5
6#[repr(u8)]
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum AgreementState {
9    Proposed = 0x00,
10    PartiallySigned = 0x01,
11    Ratified = 0x02,
12}
13
14#[derive(Debug, Clone)]
15pub struct AgreementDomain {
16    #[cfg(feature = "alloc_buffers")]
17    pub name: alloc::string::String,
18    #[cfg(not(feature = "alloc_buffers"))]
19    pub name: std::string::String,
20    pub domain_id: u64,
21}
22
23#[derive(Debug, Clone)]
24pub struct AgreementConstraint {
25    pub required_signatures: u8,
26}
27
28pub struct AgreementDID {
29    pub agreement_id: u64,
30    pub principal: u64,
31    pub agents: [u64; 8],
32    pub num_agents: u8,
33    pub domain_id: u64,
34    pub threshold: u8,
35    pub current_state: AgreementState,
36}
37
38impl AgreementDID {
39    /// Compiles a ratified agreement into hardware-aligned Super-Quins.
40    pub fn compile_to_super_quins(&self) -> [NQuin; 16] {
41        let mut buffer = [NQuin {
42            subject: 0,
43            predicate: 0,
44            object: 0,
45            context: 0,
46            metadata: 0,
47            parity: 0,
48        }; 16];
49        if self.current_state != AgreementState::Ratified {
50            return buffer;
51        }
52
53        let mut idx = 0;
54        let has_guardian = crate::q_hash("q42:hasGuardian");
55        let has_domain_scope = crate::q_hash("q42:hasDomainScope");
56        let requires_consensus = crate::q_hash("q42:requiresConsensus");
57
58        for i in 0..self.num_agents as usize {
59            if idx < 16 {
60                buffer[idx] = NQuin {
61                    subject: self.principal,
62                    predicate: has_guardian,
63                    object: self.agents[i],
64                    context: self.agreement_id,
65                    // Embed routing lane (Bilateral Micro-Commons) and the State
66                    metadata: 0x4000_0000_0000_0002 | ((self.current_state as u64) << 48),
67                    parity: 0,
68                };
69                idx += 1;
70            }
71        }
72
73        for i in 0..self.num_agents as usize {
74            if idx < 16 {
75                buffer[idx] = NQuin {
76                    subject: self.agreement_id,
77                    predicate: has_domain_scope,
78                    object: self.domain_id,
79                    context: self.agents[i],
80                    metadata: 0x4000_0000_0000_0002,
81                    parity: 0,
82                };
83                idx += 1;
84            }
85        }
86
87        if idx < 16 {
88            buffer[idx] = NQuin {
89                subject: self.agreement_id,
90                predicate: requires_consensus,
91                object: self.threshold as u64,
92                context: self.domain_id,
93                metadata: 0x4000_0000_0000_0002,
94                parity: 0,
95            };
96        }
97
98        buffer
99    }
100}
101
102/// Values abuse-check (the engine side of the MCP `values_check` tool).
103///
104/// Runs the REAL inverse rights-guard lane (agency.n3 G1 + its software-agent twin G1')
105/// in a fresh arena: a non–natural-person agent that *claims* a natural-person-only dignity
106/// right trips `values:PersonhoodCategoryError`. This is the anti-capture invariant — a
107/// `CorporatePerson` or an `ArtificialAgent` cannot wear a human's dignity right as its own.
108///
109/// `agent_type` is `q_hash("https://ns.webcivics.net/values/<Class>")`. Returns `true` iff the
110/// guard fires. A `NaturalPerson` (or a non-claiming agent) is never flagged. Cold path — uses
111/// the same `Rule`/`Formula` machinery as `register_rule`, never a hot-path allocation.
112pub fn check_personhood_category_error(agent_type: u64, claims_dignity_right: bool) -> bool {
113    use crate::modalities::logic::n3_parser::{Formula, Rule, RuleType, Term, Triple};
114    const B: &str = "https://ns.webcivics.net/values/";
115    let vh = |s: &str| crate::q_hash(s);
116    let u = |s: &'static str| Term::Uri(s);
117    let var = |n: &'static str| Term::Variable(n);
118
119    // G-guard for a given non-natural-person class: claiming a NaturalPerson-held Right → flag.
120    // `class_uri` is the FULL values: IRI of the guarded class, so its `q_hash`
121    // matches the `agent_type` fact below. Full-IRI `&'static str` literals keep
122    // this zero-heap (the predecessor leaked `format!` Strings via `Box::leak`).
123    let guard = |id: &'static str, class_uri: &'static str| Rule {
124        id: Some(id),
125        rule_type: RuleType::Strict,
126        weight: None,
127        premise: Formula {
128            triples: vec![
129                Triple {
130                    subject: var("c"),
131                    predicate: u("a"),
132                    object: u(class_uri),
133                },
134                Triple {
135                    subject: var("c"),
136                    predicate: u("https://ns.webcivics.net/values/claims"),
137                    object: var("r"),
138                },
139                Triple {
140                    subject: var("r"),
141                    predicate: u("a"),
142                    object: u("https://ns.webcivics.net/values/Right"),
143                },
144                Triple {
145                    subject: var("r"),
146                    predicate: u("https://ns.webcivics.net/values/heldBy"),
147                    object: u("https://ns.webcivics.net/values/NaturalPerson"),
148                },
149            ],
150        },
151        conclusion: Formula {
152            triples: vec![Triple {
153                subject: var("c"),
154                predicate: u("https://ns.webcivics.net/values/flag"),
155                object: u("https://ns.webcivics.net/values/PersonhoodCategoryError"),
156            }],
157        },
158    };
159
160    let mut arena = SlgArena::new();
161    let r1 = guard(
162        "agency-G1",
163        "https://ns.webcivics.net/values/CorporatePerson",
164    );
165    arena.register_rule(&r1);
166    let r2 = guard(
167        "agency-G1-prime",
168        "https://ns.webcivics.net/values/ArtificialAgent",
169    );
170    arena.register_rule(&r2);
171
172    let fact = |a: &mut SlgArena, s: u64, p: u64, o: u64| {
173        a.write_table(NQuin {
174            subject: s,
175            predicate: p,
176            object: o,
177            context: 0,
178            metadata: 0,
179            parity: s ^ p ^ o,
180        });
181    };
182    let agent = vh("urn:webcivics:values-check:agent");
183    let right = vh("urn:webcivics:values-check:right");
184    fact(&mut arena, agent, vh("a"), agent_type);
185    if claims_dignity_right {
186        fact(&mut arena, agent, vh(&format!("{B}claims")), right);
187        fact(&mut arena, right, vh("a"), vh(&format!("{B}Right")));
188        fact(
189            &mut arena,
190            right,
191            vh(&format!("{B}heldBy")),
192            vh(&format!("{B}NaturalPerson")),
193        );
194    }
195    let _ = arena.fire_registered_rules(crate::q_hash("contract:values-check"));
196    arena.has_quin(
197        agent,
198        vh(&format!("{B}flag")),
199        vh(&format!("{B}PersonhoodCategoryError")),
200    )
201}