Skip to main content

icl_core/
lib.rs

1//! ICL Core - Canonical implementation of Intent Contract Language
2//!
3//! This is the single source of truth for ICL semantics.
4//! All language bindings (Python, JavaScript, Go) compile this same core.
5//!
6//! # Architecture
7//!
8//! ```text
9//! ICL Text → Parser → AST → Normalizer → Canonical Form
10//!                              ↓
11//!                           Verifier → Type Check + Invariants + Determinism
12//!                              ↓
13//!                           Executor → Sandboxed Execution
14//! ```
15//!
16//! # Guarantees
17//!
18//! - **Deterministic**: Same input always produces identical output
19//! - **Verifiable**: All properties machine-checkable
20//! - **Bounded**: All execution bounded in memory and time
21//! - **Canonical**: One normalized form per contract
22
23pub mod error;
24pub mod executor;
25pub mod normalizer;
26pub mod parser;
27pub mod verifier;
28
29pub use error::{Error, Result};
30pub use parser::ast::*;
31
32/// Core contract definition
33#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
34pub struct Contract {
35    pub identity: Identity,
36    pub purpose_statement: PurposeStatement,
37    pub data_semantics: DataSemantics,
38    pub behavioral_semantics: BehavioralSemantics,
39    pub execution_constraints: ExecutionConstraints,
40    pub human_machine_contract: HumanMachineContract,
41}
42
43#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
44pub struct Identity {
45    pub stable_id: String,
46    pub version: u32,
47    pub created_timestamp: String, // ISO8601
48    pub owner: String,
49    pub semantic_hash: String,
50}
51
52#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
53pub struct PurposeStatement {
54    pub narrative: String,
55    pub intent_source: String,
56    pub confidence_level: f64,
57}
58
59#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
60pub struct DataSemantics {
61    pub state: serde_json::Value,
62    pub invariants: Vec<String>,
63}
64
65#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
66pub struct BehavioralSemantics {
67    pub operations: Vec<Operation>,
68}
69
70#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
71pub struct Operation {
72    pub name: String,
73    pub precondition: String,
74    pub parameters: serde_json::Value,
75    pub postcondition: String,
76    pub side_effects: Vec<String>,
77    pub idempotence: String,
78}
79
80#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
81pub struct ExecutionConstraints {
82    pub trigger_types: Vec<String>,
83    pub resource_limits: ResourceLimits,
84    pub external_permissions: Vec<String>,
85    pub sandbox_mode: String,
86}
87
88#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
89pub struct ResourceLimits {
90    pub max_memory_bytes: u64,
91    pub computation_timeout_ms: u64,
92    pub max_state_size_bytes: u64,
93}
94
95#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
96pub struct HumanMachineContract {
97    pub system_commitments: Vec<String>,
98    pub system_refusals: Vec<String>,
99    pub user_obligations: Vec<String>,
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    fn test_contract() -> Contract {
107        Contract {
108            identity: Identity {
109                stable_id: "ic-lib-test-001".into(),
110                version: 1,
111                created_timestamp: "2026-02-01T10:00:00Z".into(),
112                owner: "test".into(),
113                semantic_hash: "abc123".into(),
114            },
115            purpose_statement: PurposeStatement {
116                narrative: "Lib test contract".into(),
117                intent_source: "test".into(),
118                confidence_level: 1.0,
119            },
120            data_semantics: DataSemantics {
121                state: serde_json::json!({"message": "String", "count": "Integer"}),
122                invariants: vec!["count >= 0".into()],
123            },
124            behavioral_semantics: BehavioralSemantics {
125                operations: vec![Operation {
126                    name: "echo".into(),
127                    precondition: "input_provided".into(),
128                    parameters: serde_json::json!({"message": "String"}),
129                    postcondition: "state_updated".into(),
130                    side_effects: vec!["log".into()],
131                    idempotence: "idempotent".into(),
132                }],
133            },
134            execution_constraints: ExecutionConstraints {
135                trigger_types: vec!["manual".into()],
136                resource_limits: ResourceLimits {
137                    max_memory_bytes: 1_048_576,
138                    computation_timeout_ms: 1000,
139                    max_state_size_bytes: 1_048_576,
140                },
141                external_permissions: vec![],
142                sandbox_mode: "full_isolation".into(),
143            },
144            human_machine_contract: HumanMachineContract {
145                system_commitments: vec!["Echoes messages".into()],
146                system_refusals: vec![],
147                user_obligations: vec![],
148            },
149        }
150    }
151
152    #[test]
153    fn test_contract_serialization() {
154        let contract = test_contract();
155        let json = serde_json::to_string(&contract).unwrap();
156        let deserialized: Contract = serde_json::from_str(&json).unwrap();
157        assert_eq!(contract, deserialized);
158    }
159
160    #[test]
161    fn test_determinism_100_iterations() {
162        let contract = test_contract();
163        let input = r#"{"operation": "echo", "inputs": {"message": "determinism"}}"#;
164        let first = executor::execute_contract(&contract, input).unwrap();
165        for i in 0..100 {
166            let result = executor::execute_contract(&contract, input).unwrap();
167            assert_eq!(first, result, "Non-determinism at iteration {}", i);
168        }
169    }
170}