Intent Contract Language (ICL)
ICL is a deterministic, language-agnostic specification language for intent contracts — formal documents that describe what a system should do, how it should behave, and what it guarantees.
What is an Intent Contract?
An intent contract formally specifies:
- What a system should do (purpose and operations)
- How it should behave (preconditions, postconditions, invariants)
- What it must not do (constraints, refusals, resource limits)
- What it guarantees (commitments to the user)
Think of it like OpenAPI for human intent and AI agent constraints — but machine-checkable and deterministic.
Why ICL?
Every AI system, API, and automation tool has implicit contracts. Today, these live in:
- Natural language documentation (ambiguous)
- Type definitions (incomplete)
- Test cases (partial)
- Informal agreements (unverifiable)
ICL replaces all of these with a single, machine-checkable, deterministic format. Given the same contract and the same input, every ICL implementation produces identical output — always.
How is ICL Different from Guardrails?
| System Prompts | Guardrails | ICL | |
|---|---|---|---|
| What it is | Natural language instructions | Runtime filters | Formal, verified contracts |
| Enforcement | LLM interprets (may ignore) | Probabilistic | Mathematical proof |
| Analogy | "Please don't" | Smoke detector | Fireproof wall |
| When it fails | Silently does wrong thing | Catches some | Blocks execution, logs why |
Rule of thumb: If a violation leads to a lawsuit, death, or bankruptcy — use ICL. If it leads to a user complaint — guardrails are fine.
See the full ICL vs Guardrails & System Prompts page for 50+ real-world examples.
Quick Example
Contract {
Identity {
stable_id: "ic-hello-001",
version: 1,
created_timestamp: 2026-02-01T10:00:00Z,
owner: "developer",
semantic_hash: "e5f6a7b8c9d0"
}
PurposeStatement {
narrative: "Simple contract that echoes input messages",
intent_source: "tutorial",
confidence_level: 1.0
}
DataSemantics {
state: { message: String, count: Integer = 0 },
invariants: ["message is not empty", "count >= 0"]
}
BehavioralSemantics {
operations: [{
name: "echo",
precondition: "input_provided",
parameters: { message: String },
postcondition: "state_updated_with_message",
side_effects: ["log_operation"],
idempotence: "idempotent"
}]
}
ExecutionConstraints {
trigger_types: ["manual"],
resource_limits: {
max_memory_bytes: 1048576,
computation_timeout_ms: 100,
max_state_size_bytes: 1048576
},
external_permissions: [],
sandbox_mode: "full_isolation"
}
HumanMachineContract {
system_commitments: ["All messages are echoed"],
system_refusals: ["Will not modify past messages"],
user_obligations: ["May provide new messages"]
}
}
The ICL Ecosystem
| Repository | What It Contains |
|---|---|
| ICL-Spec | The standard — BNF grammar, core specification, conformance tests |
| ICL-Runtime | Canonical Rust implementation, CLI, and language bindings |
| ICL-Docs (this site) | Documentation you're reading now |
Core Guarantees
- Deterministic: Same input always produces identical output — no randomness, no system time dependency
- Verifiable: All contract properties are machine-checkable (types, invariants, coherence)
- Bounded: All execution is bounded in memory, time, and state size
- Canonical: One normalized form per contract, with SHA-256 semantic hashing
- Language-agnostic: One Rust core compiled to Python, JavaScript, and Go
Current Status
ICL is in active development. The core pipeline is fully implemented:
| Component | Status | Tests |
|---|---|---|
| Parser (tokenizer + recursive descent) | Complete | 80+ tests |
| Normalizer (canonical form + hashing) | Complete | 30+ tests |
| Verifier (types, invariants, determinism, coherence) | Complete | 40+ tests |
| Executor (sandbox + provenance logging) | Complete | 20+ tests |
| CLI (9 commands) | Complete | 28 tests |
| Python binding (PyO3) | Complete | 18 tests |
| JavaScript binding (WASM) | Complete | 31 tests |
| Go binding (cgo) | Complete | 16 tests |
Total: 268 tests passing — including 100-iteration determinism proofs across all components and all language bindings.
Getting Started
Ready to try ICL? Start with the Quick Start Guide.
ICL vs Guardrails & System Prompts
TL;DR: Guardrails and system prompts are suggestions an LLM can ignore or misinterpret. ICL contracts are mathematically enforced walls — verified before execution, impossible to bypass.
The Problem
A common misconception is that ICL is "just guardrails." It isn't. Here's why:
| System Prompts | Guardrails | ICL | |
|---|---|---|---|
| What it is | Natural language instructions | Runtime filters + checks | Formal, machine-verified contracts |
| Enforcement | LLM interprets (may ignore) | Probabilistic (can fail) | Mathematical (proven before execution) |
| Analogy | Asking someone "please don't" | Installing a smoke detector | Building a fireproof wall |
| Bypassed by | Jailbreaks, confusion, long context | Edge cases, adversarial input | Nothing — violations rejected before running |
| Audit trail | None | Logs (after the fact) | Provenance log with cryptographic proof |
| Determinism | No (LLM output varies) | Partial | Yes — same input = same output, always |
| When it fails | Silently does wrong thing | Catches some violations | Blocks execution, logs why |
A Concrete Example
Scenario: A trading agent must never execute trades over $10,000.
With a system prompt:
"You are a trading assistant. Never execute trades over $10,000."
→ Agent might still execute a $15,000 trade if confused, jailbroken, or if the context window fills up. You find out after losing money.
With guardrails:
if trade.amount > 10000:
block()
→ Better. But the check lives in application code, isn't portable, isn't formally verified, and can be accidentally bypassed by a code change.
With ICL:
Contract {
ExecutionConstraints {
resource_limits: { max_transaction_value: 10000 }
}
BehavioralSemantics {
operations: [{
name: "execute_trade",
precondition: "trade_amount <= 10000",
postcondition: "trade_logged_with_provenance"
}]
}
}
→ The verifier proves the constraint holds before any code runs. If an agent tries to execute a $15,000 trade, execution is blocked, the violation is logged with a cryptographic audit trail, and the system can prove to regulators that the constraint was enforced. No code change can bypass it — the contract is verified independently.
When to Use ICL
ICL is for hard constraints with real consequences — safety-critical systems, financial controls, regulatory compliance, and autonomous agents that take actions in the real world.
Autonomous Systems
| Use Case | Why ICL? |
|---|---|
| Self-driving cars | Must NEVER exceed speed limits, CANNOT enter restricted zones. One violation = fatal. |
| Delivery drones | CANNOT fly over restricted airspace, must ALWAYS return if battery < 20%. FAA compliance. |
| Surgical robots | CANNOT exceed force threshold, must ALWAYS stop if sensors fail. Life-critical. |
| Warehouse robots | CANNOT exceed weight limits, must ALWAYS stop if human in path. Worker safety. |
Financial
| Use Case | Why ICL? |
|---|---|
| Trading agents | NEVER exceed $X per trade, CANNOT trade outside hours. One mistake = bankruptcy. |
| Fraud detection | Must ALWAYS flag transactions > $Y, CANNOT auto-block without human review. Regulatory. |
| Robo-advisors | CANNOT invest in prohibited asset classes, must NEVER exceed risk tolerance. Fiduciary duty. |
| Refund bots | CANNOT approve refunds > $X without manager approval. Financial controls. |
Healthcare
| Use Case | Why ICL? |
|---|---|
| Medication dispensing | CANNOT dispense > prescribed dose, must ALWAYS verify patient ID. Patient safety. |
| Diagnostic assistants | CANNOT prescribe controlled substances, must ALWAYS flag critical values. Regulatory. |
Infrastructure & IoT
| Use Case | Why ICL? |
|---|---|
| Power grid management | CANNOT exceed capacity limits, must ALWAYS load balance. Blackout prevention. |
| Water treatment | CANNOT allow contamination > threshold. Public health critical. |
| Nuclear plant control | CANNOT exceed radiation levels, must ALWAYS initiate shutdown. Catastrophic risk. |
| Smart home security | CANNOT unlock without authentication, must ALWAYS log access. Security-critical. |
| Traffic light control | CANNOT create green-green conflicts. Safety-critical. |
Software & DevOps
| Use Case | Why ICL? |
|---|---|
| Code deployment agents | CANNOT deploy without passing tests, must ALWAYS create rollback. One mistake = outage. |
| Automated code review | CANNOT merge if security vulnerabilities found. Quality gates. |
| Data deletion agents | CANNOT delete without retention check. GDPR compliance. |
Multi-Agent Systems
| Use Case | Why ICL? |
|---|---|
| Agent orchestration | Agent A can call Agent B but CANNOT exceed data quota, must ALWAYS pass auth tokens. |
| Distributed AI | Agents must honor contracts across system boundaries. Deterministic verification needed. |
Legal & Compliance
| Use Case | Why ICL? |
|---|---|
| Contract review agents | CANNOT auto-sign > $X, must ALWAYS flag non-standard clauses. Legal liability. |
| Compliance monitoring | Must ALWAYS check against regulations, CANNOT approve if violations found. Audit trail. |
| PII handling | CANNOT expose sensitive data, must ALWAYS anonymize before sharing. Privacy law. |
When NOT to Use ICL
ICL is overkill for soft constraints, conversational AI, and analytics:
| Use Case | Why guardrails are enough |
|---|---|
| Customer support chatbots | "Be polite" and "stay on topic" — soft rules, low stakes |
| Code completion tools | Suggestions only — developer reviews before accepting |
| Smart thermostats | "Maintain comfort" — preferences, not hard constraints |
| Content recommendations | "Show relevant content" — engagement, not safety |
| Tutoring chatbots | "Be encouraging" — educational, no hard consequences |
| Crop prediction models | Analysis only, doesn't take actions |
| Legal research assistants | Finds cases, doesn't sign contracts |
| Smart lighting | Convenience feature, not safety-critical |
Decision Matrix
| Factor | → Use ICL | → Use Guardrails |
|---|---|---|
| Stakes | Life, money, data, reputation | Low consequences if wrong |
| Constraints | Hard, boolean, mathematical | Soft, subjective, fuzzy |
| Verification | Must prove to regulators/auditors | Internal quality check |
| Determinism | Same input must = same output | Probabilistic OK |
| Portability | Multiple systems share constraints | Single system |
| Safety | Failure = catastrophic | Failure = annoying |
| Compliance | Legal/regulatory requirement | Best practices |
| Execution | Agent takes actions automatically | Human reviews first |
Examples in Action
Trading Agent (ICL)
Contract specifies:
- CANNOT execute trade > $10,000
- MUST check balance before trade
- CANNOT trade outside 9:30 AM – 4:00 PM ET
Agent tries to execute $15,000 trade:
→ Verifier catches violation BEFORE execution
→ Trade blocked, error logged with provenance
→ System proves to auditors the constraint was enforced
Customer Support Chatbot (Guardrails)
System prompt:
- "Be polite and helpful"
- "Stay on topic"
- "Escalate complex issues"
Chatbot goes slightly off-topic:
→ Not catastrophic
→ Content filters catch egregious violations
→ ICL would be overkill here
Learn More
- Quick Start — Install and try ICL in 5 minutes
- Writing Contracts — Full syntax guide
- Specification Overview — The formal model
- Example Contracts — Real ICL files
Quick Start
Get up and running with ICL in under 5 minutes.
Install the CLI
cargo install icl-cli
Requires Rust. The CLI is a compiled Rust binary — it is not included in the Python or JavaScript packages.
Install Language Bindings
Python
pip install icl-runtime
Published on PyPI.
JavaScript / Node.js
npm install icl-runtime
Published on npm.
Go
cd ICL-Runtime/bindings/go/ffi
cargo build --release
Then import the Go module from bindings/go/.
Create Your First Contract
Scaffold a new contract:
icl-cli init hello
# ✓ created hello.icl
Or create hello.icl manually:
Contract {
Identity {
stable_id: "ic-hello-001",
version: 1,
created_timestamp: 2026-02-01T10:00:00Z,
owner: "developer",
semantic_hash: "e5f6a7b8c9d0"
}
PurposeStatement {
narrative: "Simple contract that echoes input messages",
intent_source: "tutorial",
confidence_level: 1.0
}
DataSemantics {
state: {
message: String,
count: Integer = 0
},
invariants: [
"message is not empty",
"count >= 0"
]
}
BehavioralSemantics {
operations: [{
name: "echo",
precondition: "input_provided",
parameters: { message: String },
postcondition: "state_updated_with_message",
side_effects: ["log_operation"],
idempotence: "idempotent"
}]
}
ExecutionConstraints {
trigger_types: ["manual"],
resource_limits: {
max_memory_bytes: 1048576,
computation_timeout_ms: 100,
max_state_size_bytes: 1048576
},
external_permissions: [],
sandbox_mode: "full_isolation"
}
HumanMachineContract {
system_commitments: ["All messages are echoed"],
system_refusals: ["Will not modify past messages"],
user_obligations: ["May provide new messages"]
}
}
Validate
Check that the contract parses correctly:
icl-cli validate hello.icl
# ✓ hello.icl is valid
Get machine-readable output with --json:
icl-cli validate hello.icl --json
# {"file":"hello.icl","valid":true,"errors":0,"warnings":2,"diagnostics":[...]}
Verify
Run full verification — types, invariants, determinism, and coherence:
icl-cli verify hello.icl
# ✓ hello.icl verified successfully
Normalize
Get the canonical form (sorted sections, sorted fields, computed hash):
icl-cli normalize hello.icl
The normalizer produces a deterministic output — running it twice always gives the same result.
Compute Hash
Get the SHA-256 semantic hash:
icl-cli hash hello.icl
# 1f7dcf67d92b813f3cc0402781f023ea33c76dd7c2b6963531fe68bf9c032cb8
Two contracts with the same semantics always produce the same hash, regardless of formatting or comment differences.
Execute
Run a contract with inputs:
icl-cli execute hello.icl --input '{"operation":"echo","inputs":{"message":"Hello"}}'
# ✓ hello.icl executed successfully
# Operations: 1
# Provenance entries: 1
Compare Contracts
Semantic diff between two contracts:
icl-cli diff v1.icl v2.icl
# Shows field-by-field differences in canonical form
Using from Python
import icl
# Parse
result = icl.parse_contract(open("hello.icl").read())
print(result) # JSON string of the parsed contract
# Normalize
canonical = icl.normalize(open("hello.icl").read())
# Verify
issues = icl.verify(open("hello.icl").read())
# Execute
output = icl.execute(
open("hello.icl").read(),
'{"operation":"echo","inputs":{"message":"Hello"}}'
)
# Semantic hash
hash_val = icl.semantic_hash(open("hello.icl").read())
Using from JavaScript
Works with Node.js (CJS or ESM), bundlers (Vite/Webpack/Rollup), and browsers.
// Node.js (CommonJS)
const { parseContract, normalize, verify, execute, semanticHash } = require('icl-runtime');
// Node.js (ES Modules) or Bundlers (Vite, Webpack, Rollup)
import { parseContract, normalize, verify, execute, semanticHash } from 'icl-runtime';
// Parse
const result = parseContract(contractText);
// Normalize
const canonical = normalize(contractText);
// Verify
const issues = verify(contractText);
// Execute
const output = execute(contractText, '{"operation":"echo","inputs":{"message":"Hello"}}');
// Semantic hash
const hash = semanticHash(contractText);
For browsers, use the /web sub-path export:
<script type="module">
import init, { parseContract } from 'icl-runtime/web';
await init(); // must call init() first
const result = parseContract(contractText);
</script>
See Integration Overview for detailed target-specific docs.
Using from Go
package main
import (
icl "github.com/ICL-System/ICL-Runtime/bindings/go"
"fmt"
)
func main() {
contract := `Contract { ... }` // your ICL text
result, err := icl.ParseContract(contract)
if err != nil { panic(err) }
fmt.Println(result)
canonical, _ := icl.Normalize(contract)
hash, _ := icl.SemanticHash(contract)
fmt.Println(canonical, hash)
}
Next Steps
- Writing Contracts — learn the full ICL syntax and type system
- CLI Reference — all 9 CLI commands
- Specification Overview — the formal model
- Architecture — how the runtime works
Writing Contracts
This guide covers the full ICL contract syntax, all sections, and the type system.
Contract Structure
Every ICL contract follows this structure:
Contract {
Identity { ... }
PurposeStatement { ... }
DataSemantics { ... }
BehavioralSemantics { ... }
ExecutionConstraints { ... }
HumanMachineContract { ... }
Extensions { ... } // optional
}
All sections except Extensions are required. Fields within a section are separated by commas.
Identity
Uniquely identifies the contract. Every field is required.
Identity {
stable_id: "ic-my-contract-001",
version: 1,
created_timestamp: 2026-02-01T10:00:00Z,
owner: "your-name",
semantic_hash: "placeholder"
}
| Field | Type | Description |
|---|---|---|
stable_id | String | Unique identifier, never changes across versions |
version | Integer | Monotonically increasing version number |
created_timestamp | ISO8601 | When this version was created |
owner | String | Author or maintainer |
semantic_hash | String | SHA-256 hash of canonical form (auto-computed by icl-cli normalize) |
The
semantic_hashis automatically recomputed when you runicl-cli normalize. You can use a placeholder during authoring.
PurposeStatement
Human-readable description of the contract's intent.
PurposeStatement {
narrative: "Manages user preferences with full audit logging",
intent_source: "human_authored",
confidence_level: 0.95
}
| Field | Type | Description |
|---|---|---|
narrative | String | What this contract does, in plain language |
intent_source | String | Who/what authored it (e.g., "human_authored", "ai_generated", "developer_specification") |
confidence_level | Float | 0.0 to 1.0 — how confident the author is in the contract's correctness |
DataSemantics
Defines the contract's state and invariants.
DataSemantics {
state: {
count: Integer = 0,
name: String,
items: Array<String>,
active: Boolean = true
},
invariants: [
"count >= 0",
"name.length <= 255"
]
}
State Fields
Each state field has a name, a type, and an optional default value:
field_name: Type = default_value
Primitive Types
| Type | Description | Example Values |
|---|---|---|
Integer | 64-bit signed integer | 0, 42, -1 |
Float | 64-bit IEEE 754 floating point | 3.14, 0.0, -1.5 |
String | UTF-8 text | "hello", "" |
Boolean | Logical value | true, false |
ISO8601 | Timestamp | 2026-02-01T10:00:00Z |
UUID | Universally unique identifier | "550e8400-e29b-41d4-a716-446655440000" |
Composite Types
| Type | Syntax | Example |
|---|---|---|
Object | Object { field: Type, ... } | Object { name: String, age: Integer } |
Enum | Enum { Variant1, Variant2, ... } | Enum { Active, Inactive, Suspended } |
Array | Array<T> | Array<String>, Array<Integer> |
Map | Map<K, V> | Map<String, Integer> |
Invariants
Invariants are string expressions that must always hold for the contract's state. The verifier checks that:
- Invariants are consistent (no contradictions)
- Invariants can be satisfied by initial state
- Operations preserve invariants
BehavioralSemantics
Defines operations — the things the contract can do.
BehavioralSemantics {
operations: [
{
name: "increment",
precondition: "count < 1000",
parameters: {},
postcondition: "count == old.count + 1",
side_effects: [],
idempotence: "not_idempotent"
},
{
name: "set_name",
precondition: "true",
parameters: { new_name: String },
postcondition: "name == new_name",
side_effects: ["log_change"],
idempotence: "idempotent"
}
]
}
| Field | Type | Description |
|---|---|---|
name | String | Operation identifier, must be unique within the contract |
precondition | String | Condition that must be true before execution |
parameters | Object | Named parameters with types |
postcondition | String | Condition that must be true after execution |
side_effects | Array<String> | Declared side effects (for transparency) |
idempotence | String | "idempotent" or "not_idempotent" |
ExecutionConstraints
Bounds for execution — resource limits and sandbox configuration.
ExecutionConstraints {
trigger_types: ["api_call", "scheduled"],
resource_limits: {
max_memory_bytes: 10485760,
computation_timeout_ms: 5000,
max_state_size_bytes: 1048576
},
external_permissions: ["network:api.example.com"],
sandbox_mode: "full_isolation"
}
| Field | Type | Description |
|---|---|---|
trigger_types | Array<String> | How the contract can be invoked ("manual", "api_call", "scheduled") |
resource_limits | Object | Memory, time, and state size bounds |
external_permissions | Array<String> | Declared external access (empty = fully sandboxed) |
sandbox_mode | String | "full_isolation", "strict", or "relaxed" |
Resource Limits
| Field | Type | Description |
|---|---|---|
max_memory_bytes | Integer | Maximum memory usage in bytes |
computation_timeout_ms | Integer | Maximum execution time in milliseconds |
max_state_size_bytes | Integer | Maximum state size in bytes |
HumanMachineContract
The social contract between the system and the user.
HumanMachineContract {
system_commitments: [
"All state changes are logged",
"No data leaves the sandbox"
],
system_refusals: [
"Will not delete data without confirmation"
],
user_obligations: [
"Must provide valid input format"
]
}
| Field | Type | Description |
|---|---|---|
system_commitments | Array<String> | What the system promises to do |
system_refusals | Array<String> | What the system explicitly will not do |
user_obligations | Array<String> | What the user is expected to do |
Extensions (Optional)
Domain-specific extensions with namespaced key-value pairs.
Extensions {
monitoring: {
alert_threshold: 0.95,
dashboard_url: "https://monitor.example.com"
},
compliance: {
framework: "SOC2",
last_audit: 2025-12-01T00:00:00Z
}
}
Extension namespaces are isolated — they cannot affect core contract semantics.
Comments
ICL supports single-line comments:
// This is a comment
Contract {
// Comments can appear anywhere
Identity {
stable_id: "example", // inline comments too
...
}
}
Comments are stripped during normalization and do not affect the semantic hash.
Complete Example
Here is a full, working contract for a database write validator:
Contract {
Identity {
stable_id: "ic-db-write-001",
version: 1,
created_timestamp: 2026-01-31T10:00:00Z,
owner: "developer-team",
semantic_hash: "auto"
}
PurposeStatement {
narrative: "Validate database writes before execution",
intent_source: "developer_specification",
confidence_level: 1.0
}
DataSemantics {
state: {
query: String,
table: String,
approved: Boolean = false
},
invariants: [
"query is not empty",
"table is not empty"
]
}
BehavioralSemantics {
operations: [
{
name: "validate_write",
precondition: "query is not empty",
parameters: { query: String, table: String },
postcondition: "approved == true",
side_effects: ["log_validation"],
idempotence: "idempotent"
}
]
}
ExecutionConstraints {
trigger_types: ["api_call"],
resource_limits: {
max_memory_bytes: 10485760,
computation_timeout_ms: 5000,
max_state_size_bytes: 1048576
},
external_permissions: [],
sandbox_mode: "full_isolation"
}
HumanMachineContract {
system_commitments: [
"All writes are validated before execution",
"Invalid writes are rejected with explanation"
],
system_refusals: [
"Will not execute unvalidated writes",
"Will not bypass validation"
],
user_obligations: [
"Must provide SQL query and target table"
]
}
}
Validate it:
icl-cli validate db-write.icl
# ✓ db-write.icl is valid
icl-cli verify db-write.icl
# ✓ db-write.icl verified successfully
Next Steps
- See more example contracts
- Read the full specification
- Explore the CLI Reference
Specification Overview
The ICL specification is maintained in the ICL-Spec repository. This page provides a summary.
Core Sections
An ICL contract consists of 7 sections (6 required, 1 optional):
- Identity — Stable ID, version, timestamp, owner, semantic hash
- PurposeStatement — Narrative description, intent source, confidence level
- DataSemantics — State definition with types and invariants
- BehavioralSemantics — Operations with pre/postconditions
- ExecutionConstraints — Resource limits, permissions, sandbox mode
- HumanMachineContract — Commitments, refusals, user obligations
- Extensions — Optional extension points for domain-specific needs
Type System
Primitives
| Type | Description | Example |
|---|---|---|
| Integer | 64-bit signed | 42 |
| Float | 64-bit IEEE 754 | 3.14 |
| String | UTF-8 text | "hello" |
| Boolean | Logical | true |
| ISO8601 | Timestamp | 2025-01-01T00:00:00Z |
| UUID | Unique ID | "550e8400-..." |
Composites
| Type | Description | Syntax |
|---|---|---|
| Object | Structured record | Object { name: String, age: Integer } |
| Enum | Tagged union | Enum { Active, Inactive, Suspended } |
| Array | Ordered collection | Array<String> |
| Map | Key-value | Map<String, Integer> |
Determinism Requirements
Every ICL implementation MUST guarantee:
- Same input → same output (no randomness)
- No system time dependency in core logic
- BTreeMap not HashMap (ordered iteration)
- All floating point operations use IEEE 754 semantics
Formal Grammar
The complete BNF grammar is available at: ICL-Spec/grammar/icl.bnf
Full Specification
Read the complete specification: CORE-SPECIFICATION.md
Architecture
The ICL Runtime processes contracts through a four-stage pipeline.
Pipeline
ICL Text → Parser → AST → Normalizer → Canonical Form
↓
Verifier → Type Check + Invariants + Determinism + Coherence
↓
Executor → Sandboxed Execution + Provenance Logging
Each stage is independent and can be used standalone.
Components
Parser (icl-core::parser)
Converts ICL text into a typed Abstract Syntax Tree (AST).
- Tokenizer (
parser::tokenizer): Character-by-character scanning produces a stream of typed tokens — keywords, identifiers, strings, integers, floats, ISO8601 timestamps, UUIDs, operators, and delimiters. Reports errors with line/column numbers. - AST (
parser::ast): Defines all AST node types matching the BNF grammar —ContractNode,IdentityNode,TypeExpression,OperationNode, etc. - Parser (
parser::parse_contract): Recursive descent parser. Handles all 7 contract sections, type expressions (primitives, composites, collections), and error recovery.
Normalizer (icl-core::normalizer)
Transforms contracts into a deterministic canonical form.
- Sorts sections alphabetically
- Sorts fields within each section
- Strips all comments and normalizes whitespace
- Expands type shorthands to full forms
- Fills in defaults
- Computes SHA-256 semantic hash of the canonical output
- Guarantees idempotence:
normalize(normalize(x)) == normalize(x)
Verifier (icl-core::verifier)
Validates contracts against the ICL specification. Four verification passes:
- Type Checker — Validates all types (primitives, composites, collections), checks parameter/postcondition consistency, enforces no implicit coercion
- Invariant Verifier — Checks invariants are satisfiable, consistent (no contradictions), and preserved by all operations
- Determinism Checker — Detects randomness, system time access, external I/O, floating-point non-determinism, and hash iteration order dependencies
- Coherence Verifier — Checks precondition/postcondition consistency, detects circular dependencies, verifies resource limits are feasible
Executor (icl-core::executor)
Runs contracts in a sandboxed environment:
- Evaluates preconditions before execution
- Applies operation with given inputs
- Verifies postconditions after execution
- Enforces resource limits (memory bytes, computation timeout, state size)
- Records all state changes in a provenance log
- No WASM needed — ICL is declarative, execution is simulated
Crate Structure
ICL-Runtime/
├── crates/
│ ├── icl-core/ # Library crate — all logic
│ │ └── src/
│ │ ├── lib.rs # Public types (Contract, Identity, etc.)
│ │ ├── parser/
│ │ │ ├── mod.rs # parse_contract()
│ │ │ ├── tokenizer.rs # Token scanning
│ │ │ └── ast.rs # AST node types
│ │ ├── normalizer.rs # normalize()
│ │ ├── verifier.rs # verify_contract()
│ │ ├── executor.rs # execute_contract()
│ │ └── error.rs # Error types
│ └── icl-cli/ # Binary crate — CLI interface
│ └── src/
│ └── main.rs # clap commands
├── bindings/
│ ├── python/ # PyO3 + maturin
│ ├── javascript/ # wasm-bindgen + wasm-pack
│ └── go/ # cgo + cbindgen
└── tests/
├── integration/ # Cross-module tests
├── conformance/ # Spec compliance
└── determinism/ # 100-iteration proofs
Determinism Architecture
Determinism is enforced at every level:
| Guarantee | How |
|---|---|
| No randomness | No rand crate, no UUID generation at runtime |
| No system time | All timestamps are inputs, never generated |
| Ordered collections | BTreeMap everywhere, never HashMap |
| Stable floating point | IEEE 754 strict semantics |
| Deterministic ordering | All iteration is sorted |
| 100-iteration proof | Every test runs 100 times, all outputs must match byte-for-byte |
Language Bindings Architecture
All bindings wrap the same Rust core — they never reimplement logic:
┌──────────────┐
│ icl-core │ ← Single Rust library
└──────┬───────┘
┌──────────────┼──────────────┐
│ │ │
┌──────┴──────┐ ┌────┴────┐ ┌───────┴──────┐
│ PyO3 (FFI) │ │ WASM │ │ cgo (FFI) │
│ maturin │ │wasm-pack│ │ cbindgen │
└──────┬──────┘ └────┬────┘ └───────┬──────┘
│ │ │
┌──────┴──────┐ ┌────┴────┐ ┌───────┴──────┐
│ Python │ │ JS/TS │ │ Go │
│ pip install │ │npm inst.│ │ go get │
└─────────────┘ └─────────┘ └──────────────┘
| Language | Technology | Package Name |
|---|---|---|
| Python | PyO3 + maturin | icl-runtime on PyPI (published on v* tag) |
| JavaScript | wasm-bindgen + wasm-pack | icl-runtime on npm |
| Go | cgo + cbindgen | github.com/ICL-System/ICL-Runtime/bindings/go |
All three expose the same 5 functions: parse, normalize, verify, execute, semantic hash.
API Reference
The icl-core library exposes a clean Rust API. All language bindings (Python, JS, Go) wrap these same functions.
Core Functions
parser::parse_contract
#![allow(unused)] fn main() { pub fn parse_contract(input: &str) -> Result<Contract> }
Parses ICL text into a Contract struct. Returns Error::ParseError on invalid syntax.
The parser uses recursive descent and handles all 7 contract sections, type expressions, and error recovery.
normalizer::normalize
#![allow(unused)] fn main() { pub fn normalize(icl: &str) -> Result<String> }
Converts ICL text to canonical form. Returns the normalized string.
Guarantees:
- Idempotent:
normalize(normalize(x)) == normalize(x) - Deterministic: same input → same output, always
- Semantic hash is embedded in the
Identity.semantic_hashfield
normalizer::semantic_hash
#![allow(unused)] fn main() { pub fn semantic_hash(icl: &str) -> Result<String> }
Computes the SHA-256 hash of the canonical form. Returns a hex string.
verifier::verify_contract
#![allow(unused)] fn main() { pub fn verify_contract(contract: &Contract) -> Result<()> }
Runs all verification passes: type checking, invariant verification, determinism analysis, and coherence checking. Returns Ok(()) if the contract passes, or Error with diagnostics.
executor::execute_contract
#![allow(unused)] fn main() { pub fn execute_contract(contract: &Contract, inputs: &str) -> Result<String> }
Executes a contract operation in a sandboxed environment. The inputs parameter is a JSON string with "operation" and "inputs" fields. Returns a JSON string with execution results and provenance log.
Core Types
Contract
#![allow(unused)] fn main() { pub struct Contract { pub identity: Identity, pub purpose_statement: PurposeStatement, pub data_semantics: DataSemantics, pub behavioral_semantics: BehavioralSemantics, pub execution_constraints: ExecutionConstraints, pub human_machine_contract: HumanMachineContract, } }
Identity
#![allow(unused)] fn main() { pub struct Identity { pub stable_id: String, pub version: u32, pub created_timestamp: String, // ISO8601 pub owner: String, pub semantic_hash: String, } }
PurposeStatement
#![allow(unused)] fn main() { pub struct PurposeStatement { pub narrative: String, pub intent_source: String, pub confidence_level: f64, } }
DataSemantics
#![allow(unused)] fn main() { pub struct DataSemantics { pub state: serde_json::Value, pub invariants: Vec<String>, } }
BehavioralSemantics
#![allow(unused)] fn main() { pub struct BehavioralSemantics { pub operations: Vec<Operation>, } }
Operation
#![allow(unused)] fn main() { pub struct Operation { pub name: String, pub precondition: String, pub parameters: serde_json::Value, pub postcondition: String, pub side_effects: Vec<String>, pub idempotence: String, } }
ExecutionConstraints
#![allow(unused)] fn main() { pub struct ExecutionConstraints { pub trigger_types: Vec<String>, pub resource_limits: ResourceLimits, pub external_permissions: Vec<String>, pub sandbox_mode: String, } }
ResourceLimits
#![allow(unused)] fn main() { pub struct ResourceLimits { pub max_memory_bytes: u64, pub computation_timeout_ms: u64, pub max_state_size_bytes: u64, } }
HumanMachineContract
#![allow(unused)] fn main() { pub struct HumanMachineContract { pub system_commitments: Vec<String>, pub system_refusals: Vec<String>, pub user_obligations: Vec<String>, } }
Error
#![allow(unused)] fn main() { pub enum Error { ParseError(String), TypeError { expected: String, found: String }, DeterminismViolation(String), ContractViolation { commitment: String, violation: String }, ValidationError(String), ExecutionError(String), NormalizationError(String), } }
All errors implement Display and std::error::Error.
Usage Example
use icl_core::parser::parse_contract; use icl_core::normalizer; use icl_core::verifier::verify_contract; use icl_core::executor::execute_contract; fn main() -> icl_core::Result<()> { let icl_text = std::fs::read_to_string("contract.icl")?; // Parse let contract = parse_contract(&icl_text)?; // Verify verify_contract(&contract)?; // Normalize let canonical = normalizer::normalize(&icl_text)?; let hash = normalizer::semantic_hash(&icl_text)?; println!("Hash: {}", hash); // Execute let result = execute_contract( &contract, r#"{"operation":"echo","inputs":{"message":"Hello"}}"#, )?; println!("Result: {}", result); Ok(()) }
Serialization
All core types derive serde::Serialize and serde::Deserialize, so they can be serialized to/from JSON:
#![allow(unused)] fn main() { let contract = parse_contract(&icl_text)?; let json = serde_json::to_string_pretty(&contract)?; let roundtrip: Contract = serde_json::from_str(&json)?; assert_eq!(contract, roundtrip); }
Implementation Guide
This guide is for developers who want to contribute to ICL Runtime or create alternative implementations.
Conformance Requirements
Any ICL implementation must:
- Parse all valid ICL contracts per the BNF grammar
- Reject all invalid contracts with clear error messages
- Normalize to the same canonical form as the reference implementation
- Produce identical semantic hashes for equivalent contracts
- Pass all conformance tests in ICL-Spec/conformance/
Determinism Checklist
Any ICL implementation must guarantee determinism. Here's what to check:
-
No random number generation (
rand,Math.random(), etc.) - No direct system time access in core logic
-
BTreeMap/ sorted maps instead ofHashMap/ unordered maps - IEEE 754 floating point operations only
- No thread-dependent ordering
- No external I/O in core (all I/O at boundaries)
- 100-iteration determinism proof for every test path
Building from Source
Prerequisites
- Rust 1.93+ (
rustup install stable) - For Python binding: Python 3.8+, maturin
- For JS binding: wasm-pack, Node.js 16+
- For Go binding: Go 1.21+, cbindgen
Build & Test
git clone https://github.com/ICL-System/ICL-Runtime.git
cd ICL-Runtime
cargo build --workspace
cargo test --workspace
Build All Bindings
# Python
cd bindings/python && pip install -e . && pytest tests/
# JavaScript
cd bindings/javascript && wasm-pack build --target nodejs && node tests/test_icl.mjs
# Go
cd bindings/go/ffi && cargo build --release
cd bindings/go && LD_LIBRARY_PATH=../../target/release go test -v
Project Structure
ICL-Runtime/
├── Cargo.toml # Workspace root
├── crates/
│ ├── icl-core/ # Library crate (all logic)
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs # Public types + re-exports
│ │ ├── parser/ # Tokenizer + AST + recursive descent
│ │ ├── normalizer.rs
│ │ ├── verifier.rs
│ │ ├── executor.rs
│ │ └── error.rs
│ └── icl-cli/ # Binary crate (CLI)
│ └── src/main.rs
├── bindings/
│ ├── python/ # PyO3 cdylib
│ ├── javascript/ # wasm-bindgen cdylib (excluded from workspace)
│ └── go/ # cgo + cbindgen
│ ├── ffi/ # Rust FFI layer (staticlib + cdylib)
│ ├── icl.go # Go wrapper
│ └── icl_test.go
└── tests/
├── integration/
├── conformance/
└── determinism/
Creating a New Language Binding
All bindings wrap the Rust core — they must not reimplement any logic.
Steps
- Create a new directory under
bindings/ - Add a thin FFI layer that calls
icl-corefunctions - Expose 5 functions: parse, normalize, verify, execute, semantic_hash
- Write tests that verify identical output to Rust
- Add 100-iteration determinism proofs
- Document installation and usage
Function Signatures
Every binding should expose these function signatures (adapted to the target language):
parse_contract(icl_text: string) -> string // Returns JSON
normalize(icl_text: string) -> string // Returns canonical ICL text
verify(icl_text: string) -> string // Returns JSON diagnostics
execute(icl_text: string, inputs: string) -> string // Returns JSON result
semantic_hash(icl_text: string) -> string // Returns hex hash
All functions take ICL text as a string and return strings. Errors are either returned as error types (Go, Rust) or raised as exceptions (Python) or thrown (JavaScript).
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Make changes with tests
- Run the full test suite:
cargo test --workspace - Verify determinism: every new test should include a 100-iteration proof
- Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
CLI Reference
The ICL CLI provides 9 commands for working with intent contracts.
Installation
# From crates.io (recommended)
cargo install icl-cli
# Or from source
git clone https://github.com/ICL-System/ICL-Runtime.git
cd ICL-Runtime
cargo install --path crates/icl-cli
Global Options
| Option | Description |
|---|---|
--quiet | Suppress non-error output (for CI usage) |
-h, --help | Print help |
-V, --version | Print version |
icl-cli validate <file>
Check syntax and types. Parses the contract and runs the verifier.
icl-cli validate contract.icl
# ✓ contract.icl is valid
icl-cli validate contract.icl --json
# {"file":"contract.icl","valid":true,"errors":0,"warnings":2,"diagnostics":[...]}
Options:
| Option | Description |
|---|---|
--json | Output results as JSON |
--quiet | Exit code only, no output |
Exit codes: 0 = valid, 1 = invalid, 2 = file error
icl-cli normalize <file>
Output the canonical form. Sections are sorted alphabetically, fields are sorted within sections, comments are stripped, and the semantic hash is recomputed.
icl-cli normalize contract.icl
# Prints canonical form to stdout
Normalization is idempotent: normalize(normalize(x)) == normalize(x).
icl-cli verify <file>
Full verification — type checking, invariant consistency, determinism analysis, and coherence verification.
icl-cli verify contract.icl
# ✓ contract.icl verified successfully
icl-cli verify contract.icl --json
# {"file":"contract.icl","verified":true,...}
Options:
| Option | Description |
|---|---|
--json | Output results as JSON |
The verifier checks:
- All types are valid and consistent
- Invariants are satisfiable and non-contradictory
- Operations preserve invariants
- No randomness, system time, or external I/O in core logic
- Preconditions and postconditions are coherent
- Resource limits are feasible
icl-cli fmt <file>
Format a contract to standard style (equivalent to normalize, written back to file or stdout).
icl-cli fmt contract.icl
# Prints formatted contract
icl-cli hash <file>
Compute the SHA-256 semantic hash of a contract.
icl-cli hash contract.icl
# 1f7dcf67d92b813f3cc0402781f023ea33c76dd7c2b6963531fe68bf9c032cb8
The hash is computed from the canonical (normalized) form. Two contracts with the same semantics produce the same hash, regardless of formatting or comments.
icl-cli diff <file_a> <file_b>
Semantic diff between two contracts. Both contracts are normalized first, then compared field by field.
icl-cli diff v1.icl v2.icl
# --- v1.icl (canonical)
# +++ v2.icl (canonical)
# Contract {
# Identity {
# - stable_id: "ic-v1-001",
# + stable_id: "ic-v2-001",
# ...
icl-cli init [name]
Scaffold a new ICL contract with all required sections.
icl-cli init my-contract
# ✓ created my-contract.icl
icl-cli init
# ✓ created my-contract.icl (default name)
The generated template includes all required sections with placeholder values — ready to fill in.
icl-cli execute <file> --input <json>
Run a contract with JSON inputs in a sandboxed environment.
icl-cli execute contract.icl --input '{"operation":"echo","inputs":{"message":"Hello"}}'
# ✓ contract.icl executed successfully
# Operations: 1
# Provenance entries: 1
Options:
| Option | Description |
|---|---|
--input <json> | JSON input with operation and inputs fields (required) |
--json | Output execution result as JSON |
The input JSON must contain:
"operation"— name of the operation to execute"inputs"— parameters matching the operation's parameter spec
Execution enforces resource limits (memory, time, state size) and logs all state changes in the provenance log.
icl-cli version
Show version information.
icl-cli version
# icl-cli 0.1.3 (icl-core 0.1.3)
# Phases complete: Parser, Normalizer, Verifier, Executor, CLI, Bindings, CI/CD, Conformance
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Validation or verification failure |
| 2 | File not found, I/O error, or execution error |
CI Integration
Use --quiet and --json for CI pipelines:
# Fail the build if any contract is invalid
icl-cli validate contracts/*.icl --quiet
# Get machine-readable results
icl-cli verify contract.icl --json | jq '.verified'
Language Bindings
All language bindings wrap the same Rust core (icl-core). They never reimplement any logic — only type conversion and FFI glue.
Every binding exposes the same 5 functions:
| Function | Python | JavaScript | Go |
|---|---|---|---|
| Parse | parse_contract(text) | parseContract(text) | ParseContract(text) |
| Normalize | normalize(text) | normalize(text) | Normalize(text) |
| Verify | verify(text) | verify(text) | Verify(text) |
| Execute | execute(text, input) | execute(text, input) | Execute(text, input) |
| Hash | semantic_hash(text) | semanticHash(text) | SemanticHash(text) |
Python (PyO3 + maturin)
Package: icl-runtime on PyPI
Install
pip install icl-runtime
Usage
import icl
# Parse a contract
result = icl.parse_contract("""
Contract {
Identity { stable_id: "test", version: 1, ... }
...
}
""")
print(result) # JSON string
# Normalize to canonical form
canonical = icl.normalize(contract_text)
# Verify (returns JSON diagnostics)
diagnostics = icl.verify(contract_text)
# Execute with inputs
output = icl.execute(contract_text, '{"operation":"echo","inputs":{"message":"Hi"}}')
# Compute semantic hash
hash_value = icl.semantic_hash(contract_text)
print(hash_value) # "1f7dcf67..."
Type Stubs
Python type stubs (.pyi) are included for IDE autocompletion:
def parse_contract(icl_text: str) -> str: ...
def normalize(icl_text: str) -> str: ...
def verify(icl_text: str) -> str: ...
def execute(icl_text: str, inputs_json: str) -> str: ...
def semantic_hash(icl_text: str) -> str: ...
JavaScript / TypeScript (wasm-pack)
Package: icl-runtime on npm
Works out of the box in Node.js, bundlers (Vite, Webpack, Rollup), and plain browsers — zero manual WASM copying. The correct target is selected automatically via conditional exports.
Install
npm install icl-runtime
Usage (Node.js — CommonJS)
const icl = require('icl-runtime');
// Parse
const parsed = icl.parseContract(contractText);
// Normalize
const canonical = icl.normalize(contractText);
// Verify
const diagnostics = icl.verify(contractText);
// Execute
const result = icl.execute(contractText, '{"operation":"echo","inputs":{"message":"Hi"}}');
// Hash
const hash = icl.semanticHash(contractText);
Usage (Node.js — ES Modules)
import { parseContract, normalize, verify, execute, semanticHash } from 'icl-runtime';
const ast = JSON.parse(parseContract(contractText));
const hash = semanticHash(contractText);
Usage (Bundlers — Vite, Webpack, Rollup)
import { parseContract, normalize, verify, execute, semanticHash } from 'icl-runtime';
// Same API — bundler target is selected automatically via "exports" → "import"
const ast = JSON.parse(parseContract(contractText));
Vite users: Add
vite-plugin-wasmto your Vite config for WASM ESM integration support.
Usage (Browser — Script Tag)
<script type="module">
import init, { parseContract } from 'icl-runtime/web';
// Must call init() first — loads the WASM binary via fetch()
await init();
const ast = JSON.parse(parseContract(contractText));
console.log(ast);
</script>
TypeScript
TypeScript definitions (.d.ts) are included — no @types package needed:
export function parseContract(icl_text: string): string;
export function normalize(icl_text: string): string;
export function verify(icl_text: string): string;
export function execute(icl_text: string, inputs_json: string): string;
export function semanticHash(icl_text: string): string;
How Target Selection Works
The npm package includes 3 pre-built WASM targets:
| Target | Loaded When | WASM Loading |
|---|---|---|
dist/nodejs/ | require() or import in Node.js | fs.readFileSync (sync) |
dist/bundler/ | import in Vite/Webpack/Rollup | Bundler handles .wasm |
dist/web/ | import from 'icl-runtime/web' | fetch() + WebAssembly.instantiate |
No manual copying of .wasm files is needed — each target's glue code loads the WASM binary from the correct relative path.
Go (cgo + cbindgen)
Module: github.com/ICL-System/ICL-Runtime/bindings/go
Install
The Go binding requires the Rust FFI library to be built first:
cd ICL-Runtime
cargo build --release -p icl-ffi
Usage
package main
import (
icl "github.com/ICL-System/ICL-Runtime/bindings/go"
"fmt"
"log"
)
func main() {
contract := `Contract { ... }`
// Parse
result, err := icl.ParseContract(contract)
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
// Normalize
canonical, err := icl.Normalize(contract)
if err != nil { log.Fatal(err) }
// Verify
diagnostics, err := icl.Verify(contract)
if err != nil { log.Fatal(err) }
// Execute
output, err := icl.Execute(contract, `{"operation":"echo","inputs":{"message":"Hi"}}`)
if err != nil { log.Fatal(err) }
// Hash
hash, err := icl.SemanticHash(contract)
if err != nil { log.Fatal(err) }
fmt.Println(canonical, diagnostics, output, hash)
}
Running Tests
cd ICL-Runtime/bindings/go
LD_LIBRARY_PATH=../../target/release go test -v
Rust (Native)
Use icl-core directly as a Rust dependency:
# Cargo.toml
[dependencies]
icl-core = "0.1"
#![allow(unused)] fn main() { use icl_core::parser::parse_contract; use icl_core::normalizer; use icl_core::verifier::verify_contract; use icl_core::executor::execute_contract; let contract = parse_contract(&icl_text)?; verify_contract(&contract)?; let canonical = normalizer::normalize(&icl_text)?; let hash = normalizer::semantic_hash(&icl_text)?; }
Cross-Language Determinism
All bindings are tested with 100-iteration determinism proofs. Given the same ICL text:
- Python
normalize()== Rustnormalize()== JSnormalize()== GoNormalize() - Python
semantic_hash()== Rustsemantic_hash()== JSsemanticHash()== GoSemanticHash() - Python
execute()== Rustexecute_contract()== JSexecute()== GoExecute()
This is guaranteed because all bindings call through to the same compiled Rust code.
Testing Guide
ICL has 268 tests across Rust, Python, JavaScript, and Go. Every test proves determinism.
Running Tests
Rust (core + CLI)
cd ICL-Runtime
cargo test --workspace
# 203 tests passing (175 icl-core + 28 icl-cli)
Python
cd ICL-Runtime/bindings/python
pip install -e .
pytest tests/
# 18 tests passing
JavaScript
cd ICL-Runtime/bindings/javascript
wasm-pack build --target nodejs
node tests/test_icl.mjs
# 31 tests passing
Go
cd ICL-Runtime/bindings/go
LD_LIBRARY_PATH=../../target/release go test -v
# 16 tests passing
Test Categories
1. Unit Tests (in-crate)
Located alongside source code in #[cfg(test)] modules. Each module has its own tests.
cargo test -p icl-core # All core tests
cargo test -p icl-core parser # Parser tests only
cargo test -p icl-core normalizer # Normalizer tests only
cargo test -p icl-core verifier # Verifier tests only
cargo test -p icl-core executor # Executor tests only
2. Integration Tests
Located in tests/integration/. Test cross-module behavior — parsing a contract, then normalizing, verifying, and executing it.
cargo test --test '*'
3. Conformance Tests
Located in tests/conformance/. Validate the runtime against the ICL-Spec conformance suite.
conformance/valid/— contracts that must parse successfullyconformance/invalid/— contracts that must be rejected with clear errorsconformance/normalization/— input/expected pairs for canonical form
cargo test conformance
4. Determinism Tests
Located in tests/determinism/. Every test runs 100 iterations and verifies identical output.
cargo test determinism
Writing Tests
Rule 1: Every Test Must Prove Determinism
#![allow(unused)] fn main() { #[test] fn test_my_feature() { let input = "..."; let first_result = my_function(input); for _ in 0..100 { assert_eq!(my_function(input), first_result); } } }
Rule 2: No Randomness, No System Time
Tests must not depend on:
- Random number generators
- Current system time
- File system ordering
- Thread scheduling
Rule 3: Test Both Valid and Invalid Inputs
#![allow(unused)] fn main() { #[test] fn test_rejects_invalid_confidence() { let input = r#"Contract { ... PurposeStatement { confidence_level: 1.5 } ... }"#; assert!(parse_contract(input).is_err()); } }
Rule 4: Conformance Fixtures
When adding parser/normalizer features, add matching fixtures to ICL-Spec:
conformance/valid/— must parseconformance/invalid/— must be rejectedconformance/normalization/— input→canonical pairs
Cross-Language Determinism
All language bindings must produce identical results to the Rust core. The binding test suites include 100-iteration determinism proofs:
Python:
def test_normalize_determinism():
first = icl.normalize(contract_text)
for _ in range(100):
assert icl.normalize(contract_text) == first
JavaScript:
const first = icl.normalize(contractText);
for (let i = 0; i < 100; i++) {
assert.strictEqual(icl.normalize(contractText), first);
}
Go:
first, _ := icl.Normalize(contract)
for i := 0; i < 100; i++ {
result, _ := icl.Normalize(contract)
if result != first {
t.Fatalf("Non-determinism at iteration %d", i)
}
}
Test Counts by Component
| Component | Tests | Includes Determinism Proof |
|---|---|---|
| Parser (tokenizer + AST + recursive descent) | ~80 | Yes |
| Normalizer (canonical form + hashing) | ~30 | Yes (idempotence + 100-iter) |
| Verifier (types + invariants + determinism + coherence) | ~40 | Yes |
| Executor (sandbox + provenance) | ~20 | Yes |
| CLI (all 9 commands) | 28 | — |
| Python binding | 18 | Yes (100-iter) |
| JavaScript binding | 31 | Yes (100-iter) |
| Go binding | 16 | Yes (100-iter) |
| Total | ~268 |