Skip to content

Architecture (ADRs)

Significant decisions are recorded as Architecture Decision Records in the repository — the why behind choices that aren’t obvious from the code. The short version:

DecisionADR
CCL compiled to a native shared library with a C ABI (GraalVM native-image); no JVM at runtime0001
The native lib is offline & stateless — caller-supplied chain data, no HTTP inside libccl0002
Four thin language wrappers over one uniform FFI0003
Bun is the only supported JavaScript runtime0004
Toolchain pinned to Oracle GraalVM 25.0.30005
TxPlan (YAML) as the transaction format0006
Plutus exec units caller-suppliable (evolved by 0013’s Scalus default)0007
Linux portability: glibc-2.17 baseline + -march=compatibility; musl as a separate artifact0008
Go pins all FFI to one dedicated OS thread (isolate thread-affinity)0010
Chain-data providers live wrapper-side0011
Native lib ships bundled in per-wrapper platform packages0012
Evaluators: Scalus offline default in core, pluggable remote in wrappers0013
Go distribution: purego + runtime library resolution0014
No reference wrapper — all four kept at parity, enforced by CI0015

(ADR-0009 was withdrawn — a release-process workflow, not an architectural decision; the number stays reserved.)

CCL (Java) is compiled by GraalVM native-image into libccl, exposing ccl_* entry points over a C ABI where data crosses as C strings (JSON/YAML/hex). Four thin wrappers — Python (ctypes), Go (purego), Rust (FFI), JS (Bun FFI) — bind the same entry-point set, verified by a CI parity check. The core is strictly offline; anything that touches the network (chain-data providers, remote evaluators) lives in the wrappers using each language’s own HTTP stack. Transactions are described in CCL’s TxPlan YAML and built offline, with Plutus execution units computed in-process by the embedded Scalus evaluator unless supplied or delegated to a remote evaluator.