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 PromptsGuardrailsICL
What it isNatural language instructionsRuntime filtersFormal, verified contracts
EnforcementLLM interprets (may ignore)ProbabilisticMathematical proof
Analogy"Please don't"Smoke detectorFireproof wall
When it failsSilently does wrong thingCatches someBlocks 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

RepositoryWhat It Contains
ICL-SpecThe standard — BNF grammar, core specification, conformance tests
ICL-RuntimeCanonical 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:

ComponentStatusTests
Parser (tokenizer + recursive descent)Complete80+ tests
Normalizer (canonical form + hashing)Complete30+ tests
Verifier (types, invariants, determinism, coherence)Complete40+ tests
Executor (sandbox + provenance logging)Complete20+ tests
CLI (9 commands)Complete28 tests
Python binding (PyO3)Complete18 tests
JavaScript binding (WASM)Complete31 tests
Go binding (cgo)Complete16 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 PromptsGuardrailsICL
What it isNatural language instructionsRuntime filters + checksFormal, machine-verified contracts
EnforcementLLM interprets (may ignore)Probabilistic (can fail)Mathematical (proven before execution)
AnalogyAsking someone "please don't"Installing a smoke detectorBuilding a fireproof wall
Bypassed byJailbreaks, confusion, long contextEdge cases, adversarial inputNothing — violations rejected before running
Audit trailNoneLogs (after the fact)Provenance log with cryptographic proof
DeterminismNo (LLM output varies)PartialYes — same input = same output, always
When it failsSilently does wrong thingCatches some violationsBlocks 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 CaseWhy ICL?
Self-driving carsMust NEVER exceed speed limits, CANNOT enter restricted zones. One violation = fatal.
Delivery dronesCANNOT fly over restricted airspace, must ALWAYS return if battery < 20%. FAA compliance.
Surgical robotsCANNOT exceed force threshold, must ALWAYS stop if sensors fail. Life-critical.
Warehouse robotsCANNOT exceed weight limits, must ALWAYS stop if human in path. Worker safety.

Financial

Use CaseWhy ICL?
Trading agentsNEVER exceed $X per trade, CANNOT trade outside hours. One mistake = bankruptcy.
Fraud detectionMust ALWAYS flag transactions > $Y, CANNOT auto-block without human review. Regulatory.
Robo-advisorsCANNOT invest in prohibited asset classes, must NEVER exceed risk tolerance. Fiduciary duty.
Refund botsCANNOT approve refunds > $X without manager approval. Financial controls.

Healthcare

Use CaseWhy ICL?
Medication dispensingCANNOT dispense > prescribed dose, must ALWAYS verify patient ID. Patient safety.
Diagnostic assistantsCANNOT prescribe controlled substances, must ALWAYS flag critical values. Regulatory.

Infrastructure & IoT

Use CaseWhy ICL?
Power grid managementCANNOT exceed capacity limits, must ALWAYS load balance. Blackout prevention.
Water treatmentCANNOT allow contamination > threshold. Public health critical.
Nuclear plant controlCANNOT exceed radiation levels, must ALWAYS initiate shutdown. Catastrophic risk.
Smart home securityCANNOT unlock without authentication, must ALWAYS log access. Security-critical.
Traffic light controlCANNOT create green-green conflicts. Safety-critical.

Software & DevOps

Use CaseWhy ICL?
Code deployment agentsCANNOT deploy without passing tests, must ALWAYS create rollback. One mistake = outage.
Automated code reviewCANNOT merge if security vulnerabilities found. Quality gates.
Data deletion agentsCANNOT delete without retention check. GDPR compliance.

Multi-Agent Systems

Use CaseWhy ICL?
Agent orchestrationAgent A can call Agent B but CANNOT exceed data quota, must ALWAYS pass auth tokens.
Distributed AIAgents must honor contracts across system boundaries. Deterministic verification needed.
Use CaseWhy ICL?
Contract review agentsCANNOT auto-sign > $X, must ALWAYS flag non-standard clauses. Legal liability.
Compliance monitoringMust ALWAYS check against regulations, CANNOT approve if violations found. Audit trail.
PII handlingCANNOT 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 CaseWhy guardrails are enough
Customer support chatbots"Be polite" and "stay on topic" — soft rules, low stakes
Code completion toolsSuggestions 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 modelsAnalysis only, doesn't take actions
Legal research assistantsFinds cases, doesn't sign contracts
Smart lightingConvenience feature, not safety-critical

Decision Matrix

Factor→ Use ICL→ Use Guardrails
StakesLife, money, data, reputationLow consequences if wrong
ConstraintsHard, boolean, mathematicalSoft, subjective, fuzzy
VerificationMust prove to regulators/auditorsInternal quality check
DeterminismSame input must = same outputProbabilistic OK
PortabilityMultiple systems share constraintsSingle system
SafetyFailure = catastrophicFailure = annoying
ComplianceLegal/regulatory requirementBest practices
ExecutionAgent takes actions automaticallyHuman 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

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

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"
}
FieldTypeDescription
stable_idStringUnique identifier, never changes across versions
versionIntegerMonotonically increasing version number
created_timestampISO8601When this version was created
ownerStringAuthor or maintainer
semantic_hashStringSHA-256 hash of canonical form (auto-computed by icl-cli normalize)

The semantic_hash is automatically recomputed when you run icl-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
}
FieldTypeDescription
narrativeStringWhat this contract does, in plain language
intent_sourceStringWho/what authored it (e.g., "human_authored", "ai_generated", "developer_specification")
confidence_levelFloat0.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

TypeDescriptionExample Values
Integer64-bit signed integer0, 42, -1
Float64-bit IEEE 754 floating point3.14, 0.0, -1.5
StringUTF-8 text"hello", ""
BooleanLogical valuetrue, false
ISO8601Timestamp2026-02-01T10:00:00Z
UUIDUniversally unique identifier"550e8400-e29b-41d4-a716-446655440000"

Composite Types

TypeSyntaxExample
ObjectObject { field: Type, ... }Object { name: String, age: Integer }
EnumEnum { Variant1, Variant2, ... }Enum { Active, Inactive, Suspended }
ArrayArray<T>Array<String>, Array<Integer>
MapMap<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"
    }
  ]
}
FieldTypeDescription
nameStringOperation identifier, must be unique within the contract
preconditionStringCondition that must be true before execution
parametersObjectNamed parameters with types
postconditionStringCondition that must be true after execution
side_effectsArray<String>Declared side effects (for transparency)
idempotenceString"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"
}
FieldTypeDescription
trigger_typesArray<String>How the contract can be invoked ("manual", "api_call", "scheduled")
resource_limitsObjectMemory, time, and state size bounds
external_permissionsArray<String>Declared external access (empty = fully sandboxed)
sandbox_modeString"full_isolation", "strict", or "relaxed"

Resource Limits

FieldTypeDescription
max_memory_bytesIntegerMaximum memory usage in bytes
computation_timeout_msIntegerMaximum execution time in milliseconds
max_state_size_bytesIntegerMaximum 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"
  ]
}
FieldTypeDescription
system_commitmentsArray<String>What the system promises to do
system_refusalsArray<String>What the system explicitly will not do
user_obligationsArray<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

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):

  1. Identity — Stable ID, version, timestamp, owner, semantic hash
  2. PurposeStatement — Narrative description, intent source, confidence level
  3. DataSemantics — State definition with types and invariants
  4. BehavioralSemantics — Operations with pre/postconditions
  5. ExecutionConstraints — Resource limits, permissions, sandbox mode
  6. HumanMachineContract — Commitments, refusals, user obligations
  7. Extensions — Optional extension points for domain-specific needs

Type System

Primitives

TypeDescriptionExample
Integer64-bit signed42
Float64-bit IEEE 7543.14
StringUTF-8 text"hello"
BooleanLogicaltrue
ISO8601Timestamp2025-01-01T00:00:00Z
UUIDUnique ID"550e8400-..."

Composites

TypeDescriptionSyntax
ObjectStructured recordObject { name: String, age: Integer }
EnumTagged unionEnum { Active, Inactive, Suspended }
ArrayOrdered collectionArray<String>
MapKey-valueMap<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:

  1. Type Checker — Validates all types (primitives, composites, collections), checks parameter/postcondition consistency, enforces no implicit coercion
  2. Invariant Verifier — Checks invariants are satisfiable, consistent (no contradictions), and preserved by all operations
  3. Determinism Checker — Detects randomness, system time access, external I/O, floating-point non-determinism, and hash iteration order dependencies
  4. 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:

GuaranteeHow
No randomnessNo rand crate, no UUID generation at runtime
No system timeAll timestamps are inputs, never generated
Ordered collectionsBTreeMap everywhere, never HashMap
Stable floating pointIEEE 754 strict semantics
Deterministic orderingAll iteration is sorted
100-iteration proofEvery 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     │
     └─────────────┘ └─────────┘ └──────────────┘
LanguageTechnologyPackage Name
PythonPyO3 + maturinicl-runtime on PyPI (published on v* tag)
JavaScriptwasm-bindgen + wasm-packicl-runtime on npm
Gocgo + cbindgengithub.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_hash field

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:

  1. Parse all valid ICL contracts per the BNF grammar
  2. Reject all invalid contracts with clear error messages
  3. Normalize to the same canonical form as the reference implementation
  4. Produce identical semantic hashes for equivalent contracts
  5. 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 of HashMap / 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

  1. Create a new directory under bindings/
  2. Add a thin FFI layer that calls icl-core functions
  3. Expose 5 functions: parse, normalize, verify, execute, semantic_hash
  4. Write tests that verify identical output to Rust
  5. Add 100-iteration determinism proofs
  6. 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

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Make changes with tests
  4. Run the full test suite: cargo test --workspace
  5. Verify determinism: every new test should include a 100-iteration proof
  6. 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

OptionDescription
--quietSuppress non-error output (for CI usage)
-h, --helpPrint help
-V, --versionPrint 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:

OptionDescription
--jsonOutput results as JSON
--quietExit 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:

OptionDescription
--jsonOutput 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:

OptionDescription
--input <json>JSON input with operation and inputs fields (required)
--jsonOutput 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

CodeMeaning
0Success
1Validation or verification failure
2File 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:

FunctionPythonJavaScriptGo
Parseparse_contract(text)parseContract(text)ParseContract(text)
Normalizenormalize(text)normalize(text)Normalize(text)
Verifyverify(text)verify(text)Verify(text)
Executeexecute(text, input)execute(text, input)Execute(text, input)
Hashsemantic_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-wasm to 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:

TargetLoaded WhenWASM Loading
dist/nodejs/require() or import in Node.jsfs.readFileSync (sync)
dist/bundler/import in Vite/Webpack/RollupBundler 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() == Rust normalize() == JS normalize() == Go Normalize()
  • Python semantic_hash() == Rust semantic_hash() == JS semanticHash() == Go SemanticHash()
  • Python execute() == Rust execute_contract() == JS execute() == Go Execute()

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 successfully
  • conformance/invalid/ — contracts that must be rejected with clear errors
  • conformance/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 parse
  • conformance/invalid/ — must be rejected
  • conformance/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

ComponentTestsIncludes Determinism Proof
Parser (tokenizer + AST + recursive descent)~80Yes
Normalizer (canonical form + hashing)~30Yes (idempotence + 100-iter)
Verifier (types + invariants + determinism + coherence)~40Yes
Executor (sandbox + provenance)~20Yes
CLI (all 9 commands)28
Python binding18Yes (100-iter)
JavaScript binding31Yes (100-iter)
Go binding16Yes (100-iter)
Total~268