Getting Started

CSSL · Sigil · Caveman Sigil Substrate Language
build · run · experiment · explore
pre-1.0 · build from source · Cranelift JIT · x86-64 + SPIR-V

§0 — Pre-release Status

Status
CSSL is pre-1.0 and actively developed. Stage-0 compiler is live: parser, AST, HIR, MIR, F1 autodiff (62/62 gates), HM type inference foundation, 1,600+ tests passing, 0 clippy warnings, 6/6 CI gates per commit. This guide walks you through building the compiler from source and experimenting with the language as it develops.

CSSL — Caveman Sigil Substrate Language, also called Sigil — is a single-source systems language that compiles to native x86-64 (AVX2 base, AVX-512 opportunistic) and SPIR-V (Vulkan 1.4 + Level-Zero). It is not yet a shipped production toolchain. What it is is a live, tested, rapidly advancing compiler with a complete v1 specification.

This guide is honest about what is implemented versus what is specified. Where a feature exists in the specification but has not landed in the stage-0 compiler yet, it is noted. The specification (25 .csl files) is complete and stable for v1.

Machine-readable versions of this guide:

§1 — Prerequisites

You need three things to build and run the CSSL compiler. GPU work adds a fourth.

Required Rust toolchain

Nightly channel, version pinned via rust-toolchain.toml in the repository. The build system will automatically download the pinned toolchain via rustup if you have rustup installed.

Required Git

To clone the repository. Any recent Git version works (2.x+).

Required C linker

On Linux: gcc or clang. On Windows: MSVC build tools (or MinGW). Cargo uses this to link the final binaries.

GPU work only Vulkan SDK

LunarG Vulkan SDK for your platform. Includes glslc, validation layers, and spirv-tools. Required only if you are targeting SPIR-V output or running GPU compute.

Supported platforms

Primary dev targets are Linux x86-64 and Windows x86-64. macOS is supported via the Metal backend stub, but primary development and testing happens on Linux and Windows. The Cranelift stage-0 backend targets x86-64.

Install Rust

If you do not have Rust: visit rustup.rs and follow the instructions for your platform. The repository's rust-toolchain.toml will select the correct nightly channel automatically.

§2 — Installation

CSSL is pre-1.0. The primary installation path is building from source. This gives you the live development build with all 1,600+ tests runnable locally.

Build from source (recommended)

1

Clone the repository

git clone https://github.com/Apocky/CSSL3
cd CSSL3

The repository contains 25 specification files in specs/, 31 compiler crates in compiler-rs/, and examples in examples/.

2

Build the compiler

cargo build --release

This builds the full workspace, including csslc (the compiler driver). The rust-toolchain.toml in the repo root pins the exact nightly version — rustup will download it automatically if needed. First build takes several minutes.

3

Add csslc to your PATH

# Linux / macOS
export PATH="$PATH:$(pwd)/target/release"

# Windows (PowerShell)
$env:PATH += ";$(Get-Location)\target\release"

Or invoke directly: ./target/release/csslc

4

Verify the build

csslc --version

You should see the compiler version string. Run the test suite to verify everything passes:

cargo test --release

Binary releases (alternative)

Pre-built binaries are available on the GitHub releases page for Linux and Windows x86-64. Because this is pre-1.0 software, builds may lag behind the tip of the development branch.

# Linux — download and install system-wide
curl -L https://github.com/Apocky/CSSL3/releases/latest/download/csslc-linux-x64 \
  -o csslc
chmod +x csslc
sudo mv csslc /usr/local/bin/
Pre-release note The compiler is under active development. CLI interface, output format, and supported features may change between releases. Building from source at HEAD gives you the most current behavior.

§3 — Your First Program

CSSL source files use the .cssl extension. Every file that is the entry point of a program or module begins with a module declaration. Functions are introduced with fn. There are no semicolons; expressions are the body.

Hello World

Create a file named hello.cssl:

module com.example.hello

fn main() {
    print("Hello from Sigil!")
}

Run it:

csslc run hello.cssl
Hello from Sigil!

The csslc run command compiles and immediately executes via the Cranelift JIT backend — the stage-0 native code generator. No intermediate files are written to disk for run; they are kept in memory and executed directly.

A function with an effect row

Effects are declared after the return type with a / separator. This function is pure on the CPU with no heap allocation — the compiler verifies this at compile time:

module com.example.effects

// A pure CPU function — no allocation, no I/O, deterministic.
fn scale_gain(sample : f32, gain : f32) -> f32
    / {CPU, NoAlloc, PureDet}
{
    sample * gain
}

fn main() {
    let out = scale_gain(0.5, 0.8)
    print(out)
}

The effect row / {CPU, NoAlloc, PureDet} is part of the function's type. If the function body were to call an allocating function, the compiler would reject it. Omitting the effect row means the compiler infers effects from the body.

Building a native binary

To compile to a standalone native binary instead of JIT-running:

csslc build hello.cssl           # native x86-64 binary
csslc build --emit spir-v hello.cssl  # SPIR-V module for Vulkan
./hello                          # run the compiled binary

§4 — Project Structure

A CSSL project is a collection of .cssl source files. Each file begins with a module declaration that names the module within a reverse-DNS namespace (following the convention in the compiler's own specification).

Single-file programs

Any .cssl file with a fn main() is a runnable program. No manifest file is required for single-file work:

module com.example.my_program

use std::math::{vec3, normalize, dot}

fn main() {
    let a = vec3(1.0, 0.0, 0.0)
    let b = vec3(0.0, 1.0, 0.0)
    let d = dot(normalize(a), normalize(b))
    print(d)  // 0.0
}

Multi-file projects

For larger projects, organize code across multiple .cssl files within the same namespace. Each file is a module. A recommended layout:

The mod.cssl at the project root is the module entry point, similar in role to lib.rs in Rust or index.ts in TypeScript. It declares the module name and re-exports the public interface:

module com.example.my_engine

pub use render::RenderGraph
pub use audio::AudioCallback
pub use physics::PhysicsWorld

Dual-surface syntax

CSSL has two syntactic surfaces that share one HIR (High-level IR): the Rust-hybrid surface (shown throughout this guide, familiar keywords, good for docs and onboarding) and the CSL-native surface (compressed, glyph-based, optimized for token density). Both parse to the same representation; a formatter round-trips losslessly between them. The examples in this guide use the Rust-hybrid surface.

§5 — Compilation & Running

The csslc driver is the single entry point for all compilation tasks. Stage-0 uses Cranelift as the code generator for x86-64 output (not LLVM — CSSL has no LLVM dependency anywhere in the pipeline). SPIR-V is emitted via rspirv from day one.

Common commands

# JIT compile and run immediately (Cranelift backend)
csslc run hello.cssl

# Compile to native binary
csslc build hello.cssl

# Compile to SPIR-V (for Vulkan / Level-Zero)
csslc build --emit spir-v hello.cssl

# Show compiler diagnostics and effect-row verification
csslc check hello.cssl

# Print the HIR for debugging
csslc dump --hir hello.cssl

The compilation pipeline

CSSL source goes through the following stages. Each stage in the stage-0 compiler is implemented; later stages are where features progressively land:

.cssl source
  → lex · parse
  → HIR          // High-level IR · type-checked · effect-checked
  → IFC check    // Information flow labels
  → MIR          // MLIR dialect · AD source-to-source here
  → SMT discharge  // Z3/CVC5 for refinement type obligations
  → LIR
  ↙               ↘
Cranelift → x86-64   rspirv → SPIR-V → Vulkan / Level-Zero
About the Cranelift backend

Cranelift is the stage-0 code generator — a deliberate throwaway bootstrapping choice. It generates correct x86-64 code quickly, which lets the compiler be developed and tested before the stage-1 bespoke x86-64 emitter is built. When stage-1 lands, it replaces Cranelift. You will not notice the difference from a user perspective. No LLVM. No MLIR dependency at runtime. No Enzyme.

Effect verification output

When the compiler verifies effect rows, it reports which obligations were discharged at compile time and which are wrapped in runtime assertions:

// audio_callback.cssl  ✓ accepted
effect-row:
  CPU             compile-time
  NoAlloc         0 heap ops
  NoUnbounded     loop bound: n/8
  Deadline<1ms>   SMT-provable
  PureDet         bit-exact cross-machine

refinement obligations: 1
  sample_rate ∈ {44100, 48000, 96000, 192000}
  → SMT query  ✓ discharged

§6 — Key Concepts

CSSL is built around five interlocking ideas. Each is a first-class part of the type system — not a library, not a runtime policy, and not opt-in. What follows is an orientation; full details are in the Sigil language reference.

F3 · Effect System

Effects

Row-polymorphic effect signatures after / in the function type. The compiler tracks what a function observes and refuses to accept functions that violate their declared row. 28+ built-in effects covering resource allocation, timing, hardware, power, thermal, and information flow.

Pony-6 · Capabilities

Linear types & capabilities

Six reference capabilities control aliasing and mutation: iso (isolated), trn (transition), ref (shared-mutable via generational ref), val (immutable-shared), box (read-only view), tag (opaque handle). Linear values may only be resumed once inside handlers — the compiler enforces this.

F5 · IFC

Information Flow Control

Decentralized Label Model (Jif-DLM): every SSA value carries confidentiality and integrity labels threaded by the compiler. The {Sensitive<dom>} effect marks sensitive domains. Explicit declassification operators are required to move data from sensitive to public context. Harm-enabling effect compositions are type errors.

F2 · Refinement Types

Refinement types

LiquidHaskell-style predicates: {v : f32 | v >= 0.0} or the shorthand tagged suffix f32'pos. Discharged by Z3/CVC5 through the {Verify<method>} effect at compile time. Lipschitz proofs, layout refinements (@layout(std140|std430)), and SDF shape invariants are all refinement types.

F1 · Autodiff

Source-to-source differentiation

Mark a function @differentiable. Use fwd_diff(fn)(args) for forward mode or bwd_diff(fn)(args).d_x for reverse mode. Lowered by source-to-source transformation on MIR — no LLVM-Enzyme, no runtime tracing. Analytic gradients for SDF normals, inverse rendering, and inverse physics are first-class.

F1 · Jets

Jet<T, N> — higher-order AD

Jet<T, N> is the dual-number type for forward-mode AD in function composition. Useful for higher-order derivatives and physically-based rendering algorithms that need gradient chains. Defined in specs/17_JETS.csl.

A taste: effects + autodiff together

This example shows both an effect row and autodiff in a single function. The SDF normal is computed analytically — no finite differences:

module com.example.sdf_intro

use std::math::{vec3, length, normalize}

// Lipschitz-1 sphere SDF — differentiable, layout-safe.
@differentiable
@lipschitz(k = 1.0)
fn sphere_sdf(p : vec3, r : f32'pos) -> f32 {
    length(p) - r
}

// Analytic surface normal via reverse-mode AD.
// GPU, must finish in 16ms, no heap allocs.
@fragment
fn surface_normal(hit_pos : vec3) -> vec3
    / {GPU, Deadline<16ms>, NoAlloc}
{
    let grad = bwd_diff(sphere_sdf)(hit_pos, 0.5).d_p
    normalize(grad)
}
// bwd_diff is a compiler-level operator — no runtime overhead,
// no tracing, no LLVM-Enzyme. Lowered at MIR before codegen.

§7 — Next Steps

You have the compiler built and a mental model of the language. Here is where to go next.

Language Reference Sigil / CSSL

Complete language reference — all 28+ effects, capability matrix, hardware targets, the full compilation pipeline, and the bug-pattern→compiler-feature mapping from the Labyrinth of Apocalypse retrospective.

Code Examples examples/ in the repo ↗

Working code in examples/: sdf_shader.cssl (F1 autodiff gate), audio_callback.cssl ({NoAlloc} + {Deadline}), hello_triangle.cssl (minimum Vulkan pipeline).

Specification Notation CSL Reference

CSL is the 74-glyph LL(2) notation used to write the CSSL specification itself. If you want to read the 25 .csl spec files in the repo, start here — it explains the grammar, glyphs, compound types, and morpheme stacking.

Compiler Source github.com/Apocky/CSSL3 ↗

31 crates in compiler-rs/. cssl-lex, cssl-parse, cssl-hir, cssl-mir, cssl-autodiff, csslc driver. CI gates: fmt · clippy · test · doc · spec-xref · reproducibility.

Quality Methodology Thinking Guides

Seven failure modes of reasoning under throughput pressure. The verification methodology used on this site. Relevant for anyone building tools or specs on top of CSSL.

Ethics Ethics Guides

Foundational ethical principles for the system. The Prime Directive — encoded structurally in CSSL's IFC labels and effect system — is not a policy document. It is a type-level invariant.

Contributing

The compiler is written in Rust with a zero-warning, zero-clippy-lint standard. Each commit must pass 6 CI gates: fmt, clippy, test, doc, spec-xref, reproducibility. See DECISIONS.md in the repository for the rationale behind key architectural choices. Session handoffs are in handoffs/.

FEEDBACK