Documentation
Build and boot your code on every chip — in CI.
cilicon cross-builds each target and boots it in an emulator (or on a real GPU), in parallel on Modal, and reports one PR check — now signed, security-gated, and root-caused. It's a step you add to your existing CI, not a new CI.
Quickstart
Two ways in. Both need a cilicon.yml and a Modal token (modal token new).
As a GitHub Action
Add it as a step; it builds + boots the matrix and posts the check on the PR.
# add cilicon as a step in your existing CI
- uses: RyanRana/cilicon@v1
env:
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
Or run it locally
$ pip install cilicon
$ modal token new # once — writes a local token
$ cilicon run # build + boot every target, in parallel
fail-on-regression or a vuln gate (see Evidence & gates).
cilicon.yml
A target is a toolchain plus a proof it actually ran. Adding a chip is a yaml entry, never a code change — 100+ boards and GPUs ship as presets.
targets:
- id: firmware/stm32
build: make
validate: qemu_system # boot it in QEMU
machine: lm3s6965evb
expect: "reached main()" # the proof it booted
flash_max: 256K # and fits the silicon
sbom: true # emit an SBOM + sign the artifact
vuln_gate: critical # fail on an unwaived critical CVE
Common fields: build, validate, expect/expect_regex, flash_max/ram_max, board (a one-word preset), and matrix (sweep one spec into many cells).
Validation tiers
The validate field picks how a target is booted:
native/qemu_user— run the binary directly (Linux/ARM/RISC-V userspace).qemu_system— full-system boot in QEMU (MCUs, SoCs); assert a boot proof line.renode— boot on a Renode machine with modeled peripherals/sensors.real_gpu— run on an actual GPU on Modal (CUDA/kernels).custom— any tier cilicon hasn't heard of, viarun:in pure yaml.
cilicon doctor validates cilicon.yml and flags weak checks in 50 ms, before a cloud run.Evidence & gates
A green cilicon check isn't just "it compiled" — it's provable, and it can gate:
- Signed evidence bundle — each green target gets a CycloneDX SBOM (syft), a keyless cosign signature, and a SLSA provenance statement. A red target is never signed.
- Vuln gate —
vuln_gate: critical | high | kevfails the check on an unwaived finding; time-boxedwaiversreport but don't gate. - Triage — a wall of red is clustered into root causes ("40 targets → 2 causes"), advisory only.
- uses: RyanRana/cilicon@v1
with:
evidence: cilicon-evidence.json # SBOM + signature + provenance
permissions:
id-token: write # keyless cosign (Fulcio + Rekor)