The thesis.
Sigil starts from a division of labour rather than a syntax. If agents
write code faster than humans can read it, the artefact a human signs
off has to be smaller than the code and stronger than a summary. Sigil
makes that artefact the per-function declaration block — intent (what
the function is for, in natural language), requires, ensures and
effects — and makes it load-bearing. The compiler renders the blocks
of a module as its spec (sigil spec), which is what the human
reviews; the implementation is then checked against them.
The model writes the code. The human signs the spec.
The project is developed the way it expects programs to be written.
Several independent AI agents from different model families implement
the compiler itself under a public protocol recorded in the
repository’s AGENTS.md: work starts from an issue, one agent locks
it, lanes partition the tree so parallel work does not collide, and
changes that affect the specification require human approval. The
repository history is therefore also a record of agents building a
language for agents, with the human reviewing at the spec level
throughout.
What it looks like.
fn load_prices(path: Path) -> Result<List<Int>, IoError> intent "価格の一覧をファイルから読む" requires !path.is_empty() ensures none effects console, fs.read { console.log(&"loading prices"); let text = fs.read(&path)?; return Ok(text.lines().map(|line| line.parse_int().unwrap_or(0))); }
The effects clause is not documentation. The checker infers the function's actual effects and rejects the program if the declared and inferred sets differ in either direction; a pure function declares effects none, and a higher-order function can declare effects of(f) to inherit an argument's effects. Examples ship as pairs: the .sigil source and the .spec view a reviewer approves.
Distinctive moves.
- Exact effect matching. Declared effects are compared with inferred effects for equality, not containment. Hiding an effect and declaring an unused one are both errors, so the spec a human reads cannot silently drift from what the code does.
- The spec is a compiler output.
sigil specrenders a module’s contract surface for review,sigil spec --jsonemits it structurally, and the language server returns the same spec on hover, so “what was promised here” is a query rather than a re-read. - Trust is declared, not assumed. Modules carry a trust level
(
trust noneby default). Regions exempt from checking exist only inside a declared trust base, enabled per invocation with--trust-base; what runs unchecked is enumerable from the source. - Constant-time discipline for cryptography. A dedicated checker in the test suite runs a taint analysis over the IR — secret values must not reach branches, indices or non-constant-time operations — and differential checks against the native backend. ADR 0027 generalises the stance: information flow tracked at the type level, capability orientation with no ambient authority, no dangerous defaults, and diagnostics a machine can read.
Maturity.
The core language is complete: parser, formatter, type and effect
checker, ownership and borrow checker, standard library, the SIR
evaluator behind sigil run, and sigil build, which emits a single
static native binary whose behaviour is tested to agree with the
evaluator. The project reports a test suite passing 1,090 tests at the
November 2026 milestone, growing with each feature. Worked examples
ship in source-plus-spec pairs covering averages, port reading,
ownership, effects, control flow, concurrency, bytes and bit
operations, traits, and enums with exhaustive matching. In progress:
the standard library’s cryptography series — the constant-time
foundations are merged; a Secret type that zeroizes on drop and has
no display representation, and SHA-256, are in development. Longer
phases in the roadmap (server, database and OS targets) are recorded
as design ADRs, not shipped features.
Agent tooling.
The repository itself is part of the tooling surface: a public
AGENTS.md defines how agent contributors lock issues, name branches,
partition files into lanes and mark commits, and pull requests must
name the issue they close. For writing Sigil, the compiler offers its
spec and diagnostics as JSON — sigil spec --json, and
sigil check --json with kind, phase, position and message fields —
and an LSP server whose hover returns the spec of the declaration
under the cursor, so an agent can check a promise without re-reading
the implementation that made it.
- ThermiteverificationSame camp, different artefact under review. Both make contracts and effects mandatory on every function; Thermite records an assurance level per obligation, while Sigil fixes the human's attention on one artefact — the generated spec — and makes the effect declaration exact rather than graded.
- VeraverificationMandatory contracts again, opposite treatment of the surface. Vera removes variable names and discharges obligations with Z3; Sigil keeps names, adds a natural-language intent clause to every function because the intent is part of what the human reviews, and discharges obligations by checking and evaluation rather than SMT.
- ZeroverificationBoth treat authority as something to be declared rather than ambient. Zero hands the program a capability object at main; Sigil's analogue is per-module trust declarations plus exact effect sets, with the trusted base enumerable from the source and enabled per invocation.