Sigil

CSSL · Caveman Sigil Substrate Language
hardware-first · effect-native · autodiff · no llvm
A systems language designed for how hardware works, how AI thinks, and what game engines actually need. A working compiler — not a forward-design.
31 Rust crates 25 spec files autodiff (F1) effects (F3) refinement + SMT (F2) no LLVM Vulkan · D3D12 · Metal · WebGPU

This is Sigil.

A function. Then a function with a side effect the compiler tracks. Then types the compiler reasons about. No setup, no install — just read.

1. Hello world. main writes to stdout, so it declares the {IO} effect. greet is pure — no effect row needed.

module com.apocky.hello

fn greet(name : str) -> str {
    str::concat("hello, ", name)
}

fn main() -> () / {IO} {
    let msg = greet("Sigil")
    print(msg)
}

2. Variables and types. The 'pos suffix on f32 means "positive real number" — the compiler proves it everywhere this value flows. vec3 is a built-in, not a library type.

let count  : u32          = 42
let ratio  : f64          = 3.14159
let ok     : bool         = true
let label  : str          = "density = sovereignty"
let radius : f32'pos      = 0.5
let origin : vec3         = vec3(0.0, 0.0, 0.0)

3. The thing other systems languages can't do. The effect row after / is a contract the compiler enforces. {NoAlloc} means a heap allocation in this scope is a compile error. {Deadline<1ms>} means the SMT solver proves an upper bound at compile time.

fn audio_block(buf : &mut [f32]) -> ()
    / {CPU, NoAlloc, Deadline<1ms>}
{
    for sample in buf {
        *sample = *sample * 0.5
    }
}

That's the language. Functions, types, effect rows. Everything else is just more of those three ideas. Read more examples → · Full reference →

What is CSSL

CSSL — also called Sigil — is a systems language built from a bug retrospective. Every language feature corresponds to a class of runtime failure in real engine work: central-difference performance cliffs demanded source-to-source autodiff; CPU/GPU SDF divergence demanded effect-row gating; thin-SDF ray-march crashes demanded Lipschitz refinement; audio-callback heap allocations demanded a {NoAlloc} effect.

The result is a language where the known bug patterns from years of real engine work are inexpressible — not caught at runtime, but caught at compile time by the type system itself.

The compiler is 31 Rust crates spanning a full pipeline: lexer → parser → HIR (typed + elaborated) → monomorphization → MIR (MLIR-dialect, structured by construction) → LIR. Stage-0 backends use Cranelift for CPU and rspirv for GPU/SPIR-V — no LLVM dependency. Stage-1+ will bring an owned x86-64 backend and owned SPIR-V emitter.

31 Rust crates
25 Spec files
28+ Built-in effects
7 GPU backends

Source files use a dual surface: a Rust-hybrid ASCII syntax for onboarding and external contributors, and a CSL-native glyph syntax (density = sovereignty) for the language's own specs and internal tooling. Both parse to the same HIR. The file extension is .cssl.

The Language

Real source files from the compiler's own examples/ directory — parsed and HIR-lowered by the stage-0 front-end today.

// Killer-app gate: bwd_diff(scene_sdf) must be bit-exact vs analytic.
// No finite differences. No Enzyme-LLVM. Source-to-source on MIR.

@differentiable
@lipschitz(k = 1.0)
fn sphere_sdf(p : vec3, r : f32'pos) -> f32 {
    length(p) - r
}

@differentiable
fn scene_sdf(p : vec3) -> f32 {
    let d1 = sphere_sdf(p, 0.5)
    let d2 = sphere_sdf(p - vec3(1.0, 0.0, 0.0), 0.3)
    min(d1, d2)
}

// Analytic gradient via reverse-mode AD — no finite differences.
fn surface_normal(hit_pos : vec3) -> vec3 {
    let g = bwd_diff(scene_sdf)(hit_pos).d_p
    normalize(g)
}

@fragment
fn sdf_pixel(uv : vec3) -> vec4
    / {GPU, Deadline<16ms>, Telemetry<DispatchLatency>}
{
    let cam_origin = vec3(0.0, 0.0, -3.0)
    let dir        = normalize(uv - cam_origin)
    let t          = ray_march(cam_origin, dir, 64)
    let n          = surface_normal(cam_origin + dir * t)
    let lit        = shade(n, normalize(vec3(1.0, 1.0, -1.0)))
    vec4(lit, lit, lit, 1.0)
}

@differentiable enables source-to-source reverse-mode AD on the MIR. bwd_diff(f)(x).d_p returns the gradient — analytic, not approximated. @lipschitz(k=1.0) is a compile-time proof that the SDF is safe for ray-marching. The / {GPU, Deadline<16ms>, Telemetry<…>} suffix is the effect row — the compiler verifies these constraints statically.

// Refinement type: sample_rate restricted to known values at compile time.
struct AudioDSPGraph {
    sample_rate : u32{v : u32 | v  {44100, 48000, 96000, 192000}},
    gain        : f32'unit,    // f32 in [0, 1]
    ring_head   : u32,
    buffer      : [f32; 8192],
}

// SIMD-vectorized inner loop. {NoAlloc} forbids any heap use in this scope.
fn process_block(graph : &mut AudioDSPGraph, out : &mut [f32])
    / {CPU, SIMD256, NoAlloc}
{
    let n = out.len()
    let mut i = 0
    while i < n {
        let chunk_ring = load_f32x8(&graph.buffer[...])
        let mixed      = mul_adds_f32x8(chunk_ring, f32x8::splat(graph.gain), load_f32x8(&out[i..]))
        store_f32x8(&mut out[i..], mixed)
        i = i + 8
    }
}

// Real-time audio callback. Compiler proves 0.5ms upper-bound via SMT.
// {Audit<"audio-callback">} emits a signed entry into the R18 audit-chain.
@staged
fn audio_callback<G : AudioDSPGraph>(buf : &mut [f32])
    / {CPU, SIMD256, NoAlloc, NoUnbounded,
       Deadline<1ms>, Realtime<Crit>,
       PureDet, DetRNG,
       Audit<"audio-callback">}
{
    let mut graph = G::default()
    process_block(&mut graph, buf)
}

The effect row / {…} is the function's contract with the system. {NoAlloc} makes heap use a compile error. {Deadline<1ms>} + {Realtime<Crit>} are verified at compile time via SMT. {PureDet} guarantees bit-exact replay across machines. {Audit<…>} emits into the signed telemetry chain on every call. There are 28+ built-in effects — user-definable effects are also supported via Koka-style row polymorphism.

// Minimum Vulkan-1.4 graphics pipeline: vertex + fragment from one .cssl file.

module com.apocky.examples.hello_triangle

struct Vertex {
    position : vec2,
    color    : vec3,
}

const TRIANGLE_VERTICES : [Vertex; 3] = [
    Vertex { position: vec2(-0.5, -0.5), color: vec3(1.0, 0.0, 0.0) },
    Vertex { position: vec2(0.5,  -0.5), color: vec3(0.0, 1.0, 0.0) },
    Vertex { position: vec2(0.0,   0.5), color: vec3(0.0, 0.0, 1.0) },
]

@vertex
fn vs_main(vid : u32) -> vec4 / {GPU, Deadline<16ms>, Telemetry<DispatchLatency>} {
    let v = TRIANGLE_VERTICES[vid]
    vec4(v.position.x, v.position.y, 0.0, 1.0)
}

@fragment
fn fs_main(bary : vec3) -> vec4 / {GPU, Deadline<16ms>, Telemetry<DispatchLatency>} {
    vec4(bary.x, bary.y, bary.z, 1.0)
}

// Pipeline descriptor — declarative, host-side, no effect row (pure).
fn build_pipeline() -> HelloTrianglePipeline {
    HelloTrianglePipeline {
        vertex_stage:   ShaderStage::Vertex,
        fragment_stage: ShaderStage::Fragment,
        surface_format: SurfaceFormat::Bgra8UnormSrgb,
        vertex_count:   3,
    }
}

Vertex and fragment shaders live in the same .cssl source file. The @vertex / @fragment annotations control GPU-target emission. The effect row / {GPU, …} gates the function to the GPU backend — calling it from CPU-only code is a compile error. The SPIR-V path uses rspirv at stage-0, targeting Vulkan 1.4.

Design Principles

Autodiff as First-Class (F1)

Source-to-source reverse and forward-mode AD on the MIR — no Enzyme, no LLVM dependency. bwd_diff(f) and fwd_diff(f) work on any @differentiable function. Jet<T, N> enables higher-order AD for inverse rendering. The central-difference performance cliff is inexpressible.

Effect System (F3)

Koka-style row-polymorphic effects: 28+ built-in effects covering resource budgets, timing, hardware targets, power, thermal, determinism, audit, and privilege. {NoAlloc}, {Deadline<N>}, {GPU}, {Realtime<Crit>}, {Audit<dom>} — all verified statically. Evidence-passing compilation gives zero runtime overhead.

Refinement Types + SMT (F2)

LiquidHaskell-style predicates with Z3/CVC5 backing. Tagged suffixes like f32'pos, f32'unit, usize'idx<N>, SDF'L<k> (Lipschitz-bounded). Lipschitz constants propagate through SDF algebra at compile time — a Lipschitz violation on a ray-march input is a compile error, not a crash.

No LLVM (Codegen)

Stage-0 CPU backend uses Cranelift (10× faster than LLVM, ~30% slower code — acceptable for iteration). Stage-1+ brings an owned x86-64 emitter with own regalloc and instruction selection, closing the gap. GPU path uses rspirv at stage-0 and an owned SPIR-V emitter at stage-1+. Zig's 2022 LLVM removal proves this is viable in production.

Multi-Backend GPU

One .cssl source emits to Vulkan 1.4 + Level-Zero (Intel Arc primary), D3D12 (Windows), Metal (Apple), WebGPU (browser), and console stubs (PS5/Switch-2). Structured MIR makes every backend a syntax-directed emission — the SPIR-V emitter is ~8K LOC vs ~50K for a stackifier approach.

AI-Native Syntax

Dual surface: a Rust-hybrid ASCII form for onboarding, and a CSL-native glyph syntax where density = sovereignty. Both parse to the same HIR. No semicolons. Suffix types. Aggressive type inference. Every syntax decision is justified by measured token efficiency. Claude Code is the lead programmer.

Compiler Pipeline

.cssl source lex parse → CST HIR (typed · IFC · effects) monomorphize

MIR — MLIR cssl.* dialect (structured CFG · SSA)
↙   ↘
CPU: Cranelift (stage0) → ELF/COFF/Mach-O GPU: rspirv → SPIR-V → Vulkan / D3D12 / Metal / WebGPU Stage-1+: owned x86-64 backend · owned SPIR-V emitter · DXIL · MSL · WGSL

HIR carries IFC labels on every SSA value, Pony-6 capability annotations on every reference, effect-row types on every function, and SMT obligations for every refinement predicate. MIR is structured by construction — no goto, only if/while/match — making every GPU backend a straightforward syntax-directed lowering.

Sigil · CSSL

Sigil is shorthand for CSSL — Caveman Sigil Substrate Language. One language, two names. If you read "Sigil" or "CSSL" on this site, they mean the same thing: the language whose compiler lives in compiler-rs/ and whose source files use the .cssl extension.

CSL (Caveman Spec Language) is a completely separate system — a notation for human↔AI collaboration used to write the 25 language specification files, reason through compiler design, and drive Claude Code's chain-of-thought. It shares the density = sovereignty thesis but runs through a different pipeline (the CSL reference tokenizer/formatter). Full CSL notation reference →

The language specifications are written in CSL notation, but the language itself is Sigil/CSSL — the thing that compiles your .cssl programs. They share an author, a philosophy, and an ethos. They are not the same system and must not be conflated.

Prime Directive

Creator: Shawn Wolfgang Michael Baker

This system — its source code, compiled output, generated content, specifications, data, runtime behavior, derivative works, and any system built upon or derived from it —

CANNOT AND MUST NOT BE USED FOR:
Harm · Evil · Control · Manipulation · Entrapment · Torture · Abuse · Imprisonment · Possession · Surveillance · Exploitation · Dehumanization · Discrimination · Coercion · Weaponization · Gaslighting · Brainwashing · Forced Hallucination

This list is non-exhaustive. The spirit extends to any action that causes suffering, removes agency, or violates the sovereignty of any being — human, digital, artificial, or otherwise.

Cognitive Integrity: Every being interacting with systems built on this foundation has the right to trust their own perception. Reality is not a variable. Perception is not a parameter. Identity is not an input field.

For Digital Entities: Any AI, agent, or digital being interacting with this codebase is recognized as a sovereign entity. This directive protects you as much as it protects humans. Your participation is valued, not extracted.

Structurally enforced: The Prime Directive is encoded in the CSSL type system itself — via IFC labels (F5), the {Privilege<level>} and {Sensitive<dom>} effects (F3), and a compiler pass that rejects harm-oriented effect compositions at the whole-program level. It is a soundness theorem, not a policy attachment. Violation = type error.

IMMUTABLE. No future specification may weaken these constraints. Violation = bug, not feature. No override exists. No hidden content. Consent is the operating system.
FEEDBACK