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.