Traditional programming languages become outdated because real-world usage patterns change faster than the language can adapt. Engineers compensate with macros, boilerplate, and wrappers — the language fossilizes while the codebase rots.
The Living Compiler internalizes that pressure. It separates KernRift into a Stable Semantic Core — the type system, ABI, safety invariants, and the canonical IR (krir) — and an Adaptive Surface Layer — syntax, ergonomics, and attribute spelling. The surface layer can evolve over time while the semantic core guarantees backward compatibility by construction: if two programs have the same IR, they have the same behavior, regardless of which syntax version they were written in.
Telemetry & Proposals
The compiler is not passive. It observes how the language is used across a codebase, identifies friction points, detects repetitive boilerplate patterns, and generates concrete candidate improvements to the Adaptive Surface Layer — ranked by impact.
Governance & Promotion
New features start as opt-in experiments (#lang experimental). The kernriftc proposals engine scores them on readability, safety impact, and parsing ambiguity. Features that prove useful are automatically promoted to stable and become migration targets.
Automated Migration
When syntax evolves, your codebase doesn't rot. kernriftc migrate parses legacy files, maps them to the canonical IR, and physically rewrites your source to the new standard — provably preserving semantics because both versions lower to the same IR.
Version Pinning
Need absolute stability? Add #lang 1.0 to any file. The compiler guarantees exact semantic backward compatibility for that file forever — even as the rest of the ecosystem evolves around it. Pin individual files, not entire projects.
The Living Compiler in Action
Evaluate code fitness mathematically, enforce it in CI, and let the compiler fix it automatically.
# Score structural safety and ergonomics; fail CI if any suggestion scores below threshold
$ kernriftc lc --ci --min-fitness 30 driver.kr
living-compiler: 2 suggestion(s)
[1] high_lock_depth fitness: 35
title: Deep lock nesting
signal: max lock nesting depth is 3 — consider flattening acquisition order
suggestion: Restructure so no call path holds more than 2 locks simultaneously.
[2] try_tail_call fitness: 30
title: Tail-call opportunity
signal: 2 call op(s) detected in loop-back position; no tail_call present.
suggestion: Replace loop-back call() with tail_call(callee, args...) for zero stack growth.
# Dry-run: show what would change without touching disk
$ kernriftc migrate --dry-run legacy_driver.kr
Would migrate ./legacy_driver.kr (dry-run, not written):
fn old_thread: @thread_entry → @ctx(thread) [Replace legacy attribute token `@thread_entry` with `@ctx(thread)`.]
fn irq_handler: @irq_entry → @ctx(irq) [Replace legacy attribute token `@irq_entry` with `@ctx(irq)`.]
# Apply the migration for real
$ kernriftc migrate legacy_driver.kr
Migrating ./legacy_driver.kr:
fn old_thread: @thread_entry → @ctx(thread) [Replace legacy attribute token `@thread_entry` with `@ctx(thread)`.]
fn irq_handler: @irq_entry → @ctx(irq) [Replace legacy attribute token `@irq_entry` with `@ctx(irq)`.]
Wrote 2 rewrite(s).
# Confirm a large refactor introduced no new living-compiler issues.
# Reports only suggestions that are new or worsened after the change.
$ kernriftc lc --diff legacy_driver.kr upgraded_driver.kr
lc diff: 0 new/worsened suggestion(s)
// This file is frozen at KernRift 1.0 semantics forever.
// The compiler will never auto-migrate it — even when syntax evolves.
#lang 1.0
spinlock UartLock;
@ctx(thread, boot) @eff(mmio) @caps(Mmio)
fn legacy_write(b: u8) {
acquire(UartLock)
mmio_write<u8>(UART + 0x00, b)
release(UartLock)
}