二面刃 — THE TWO-EDGED LANGUAGE

Two Faces.
One Truth.

Rust made one axis visible: memory. Janus makes the larger claim. Memory, concurrency, side effects, authority, termination, preconditions, compile-time behavior, and determinism should be visible to the compiler; not buried in discipline, comments, or tribal folklore. Write what your code does. Let the compiler prove what it cannot do. Eight axes. One doctrine. Systems programming without hidden lies.

60K+ Lines of Code
1,771 Tests Passing
25 Hinge Modules
116 Example Programs
Read the 8-Axis Thesis See the Code View Source → Why Janus → Hinge Ships ✓
Release Timeline
April 22
v2026.4.8

Phase Sigils:script Profile Ships — Language Reference Codified

Three-phase sigil system: § (compile-time), $ (extraction), @ (metadata). One sigil, one phase — no cross-world aliasing. Old $size_of migrates to §size_of (W5001 deprecation). :script profile ships: implicit defaults, top-level statements, $1/$2/$* positional sugar, AOT-cached execution. Every .jans program desugars mechanically to legal :core — throwaway now, promote later, never rewrite. Language Reference v2026.4.8: the single-source doctrine. Two Structural Laws codified — do...end for flow, { } for data. Memory Authority Types (Buffer, OwnedSlice[T], Arena) ratified. No ambient allocators. Conversion trichotomy in std.conv: widen[T] (total), to[T] (fallible), truncate[T] (lossy) — zero-allocation, mechanism over policy.

April 7
v2026.4.7

Native Trig Sovereignty – Polar Embeddings – :compute Phase 0

First sovereign math library: 22 native polynomial trig functions replace graft c "math.h" entirely. Zero C dependency. All comptime-eligible. FDLIBM minimax polynomials, Cody-Waite range reduction. Integer trig fast path: std.math.trig_int – pure Janus, zero FPU, for BitNet × PolarQuant multiplication-free inference. Polar embeddings: std.compute.polar – N-dimensional hyperspherical coordinates, the first polar embedding type in any systems language.

March 31
v2026.3.31

Law 10..defaults — Match Overhaul — Generics — C FFI

Struct Initialization Completeness (Law 10): ..defaults spread – all fields required unless you opt in. Eliminates silent bugs when struct fields are added. Match overhaul: else replaces _ as match wildcard (one symbol, one meaning). .Variant patterns type-inferred from match subject. Also: Zig 0.16 migration complete, graft c / graft zig FFI, generics with monomorphization, LLVM codegen fixes, dependency cache hardening.

March 22
v2026.3.22

use jan — Multi-File Programs — Content-Addressed Modules

Janus programs can now span multiple files. use math discovers, parses, and links math.jan automatically. Qualified calls (math.add(21, 21)) resolve through module-aware lowering. Selective imports (use math { sin, cos }), aliases (use crypto.hash as h), relative imports (use .sibling). Every module gets a BLAKE3 content-addressed CID – identity is content, not filesystem path. Cycle detection prevents infinite recursion. ModuleIndex tracks path→CID mappings. 36 new tests across 4 suites. Green build: 1,771 tests passing.

March 21
v2026.3.23

janus fmt — Lockfile Build — :service Green

janus fmt ships — canonical formatter with 34 idempotency-verified tests. --check mode with line-by-line diff output for CI. Dogfooded on 1,056-line production file. janus build reads janus.lock — compiles dependencies from local registry, links into binary. :service profile fully green — nested using verified at 3 levels. Hinge integration: deduplicated modules, proper KDL serialization, transitive lockfile. println compiler fix. Formatter specification committed.

March 18
v2026.3.18

Comptime Primitives — $Meta-Sigil Builtins

First-class compile-time evaluation. comptime do...end blocks, §size_of/§type_info compile-time sigil builtins. Checked arithmetic. 14 builtins. 1,700+ tests.

March 17
v2026.3.15

Parser Expansion — Struct Methods — Type Fixes

+1,500 line parser overhaul. ++ concatenation operator. @ builtin prefix. Struct methods, const decls, default field values. Anonymous enums with backing types. fn alias for func. Monomorph cache memory leak eliminated. i32→i64 type widening for string and array ops. Hinge registry HTTP scaffold.

March 16
v2026.3.14

Native ZSTD — TLS — GTP Transport

Pure Janus ZSTD codec (RFC 8878, zero dependencies). Native TLS backend via std.net.tls. HTTPS wired into HTTP client. std.gtp and std.hinge stdlib modules. Graf integration for Hinge — publish, lockfile migration, graf.lock.json. Supertrait syntax and oracle. 236-test HTTP stack.

March 12
v2026.3.12

Go-lang Feature Parity — :service Profile

:service profile pipeline complete. std.crypto with L1 SoulKey identity. SBI module (std.sbi). Base32 and KDL encoders. Socket primitives. Sovereign Binary Interface bridge. Capsule structure for crypto, hash, and time.

March 9
v2026.3.10

Self-Documenting ASTDB — Hinge Package Manager

Documentation as structured data in the ASTDB. janus doc generates Markdown from /// comments. janus query --doc filters by predicate. Hinge sovereign supply chain (25 modules, 18K LOC). Generic monomorphization, supertrait propagation, std.core.conv.

Three Laws. Zero Exceptions.

Every design decision in Janus flows from three immutable principles.

Syntactic Honesty

The source code, the intermediate representation, and the final binary all tell the same story. No hidden transformations. No magic. You read the code; you know what it does.

"An honest abstraction is a weapon. A magical one is a trap."

Mechanism > Policy

The compiler provides levers; not opinions. Janus gives you the simplest correct mechanism and lets you decide the policy. No defaults that secretly optimize against your intent.

"The compiler decides nothing for you; it only exposes the levers you must learn to pull."

Revealed Complexity

If something is expensive, the syntax makes it visible. Dynamic dispatch costs cycles? You see &dyn Trait. Allocation happens? You see the allocator. The cost is always in the code.

"Reveal the cost. Every allocation is a blade drawn."

Code That Reads Like Intent

Beautiful syntax. Honest semantics. No exceptions; no sugar in :core.

hello.jan :core
// The simplest honest program.
func main() do
  println("Hello, Sovereign World.")
end
oneliners.jan expressive
// Verbose? Never. Janus is as terse as you want it to be.

func clamp(x: i64, lo: i64, hi: i64) -> i64 = match x { _ if x < lo => lo, _ if x > hi => hi, _ => x }

func is_prime(n: i64) -> bool = n > 1 and for 2..isqrt(n)+1 do |i| n % i != 0 end

func fizzbuzz(n: i64) -> string = match (n%3, n%5) { (0,0) => "FizzBuzz", (0,_) => "Fizz", (_,0) => "Buzz", _ => itoa(n) }

// Same language. Same compiler. Your call.
traits.jan traits + dispatch
trait Drawable {
  func draw(self) -> i32
}

struct Circle { radius: i32 }

impl Drawable for Circle {
  func draw(self) -> i32 do
    return self.radius * 2
  end
}

// Dynamic dispatch. Cost is visible.
func render(d: &dyn Drawable) -> i32 do
  return d.draw()
end
errors.jan error handling
func parse_port(s: string) -> i32 ! ParseError do
  let n = to_int(s) catch |e| do
    fail ParseError.InvalidNumber
  end
  if n < 0 or n > 65535 do
    fail ParseError.OutOfRange
  end
  return n
end
concurrency.jan structured concurrency
func fetch_all(urls: []string) do
  nursery |n| do
    for url in urls do
      n.spawn(async fetch(url))
    end
  end // All tasks complete or cancel here.
end
identity.jan zig fusion
const Ed25519 = std.crypto.sign.Ed25519;

pub const SoulKey = struct {
    seed:   [32]u8,
    public: [32]u8,

    pub fn sign(self: *const SoulKey, msg: []const u8) [64]u8 do
        const kp = Ed25519.KeyPair
            .generateDeterministic(self.seed) catch return .{0} ** 64;
        return kp.sign(msg, null).toBytes();
    end
}; // Zig types. Janus syntax. One binary.
janus.kdl hinge
// Sovereign package manifest.
project {
  name "myservice"
  version "1.0.0"
  profile "service"
}

dependencies {
  crypto "^2.1.0" // Verified supply chain
}

// Ed25519 signed. BLAKE3 content-addressed.
// Publish: janus pkg publish --key id.key

The Compilation Pipeline

Janus compiles through Zig to LLVM to native. Not a transpiler – one fused compilation unit. Every stage is inspectable.

.jan Source
Your code
Tokenizer
1,301 LOC
Parser
4,538 LOC
ASTDB
Queryable DB
QTJIR
SSA IR ~8K LOC
LLVM
3,900 LOC
Native Binary
Your machine

One Language. Six Profiles.

Start simple. Scale to sovereign. No rewrite required.

:core Teaching and fundamentals. Pure algorithms, clean syntax. No footguns. feels like Python
:script REPL and rapid prototyping. Dynamic feel, static guarantees. feels like Lua
:service Network services and applications. Async, channels, structured concurrency. feels like Go
:cluster Distributed systems. Actors, mailboxes, fault-tolerant messaging. feels like Erlang
:compute GPU, NPU, tensor operations. Scientific computing at the metal. feels like Julia
:sovereign Bare-metal ops, effects, MMIO. The full power of Janus when you need it. Effects system, capability security, comptime allocation. Your code runs at the metal. is Zig – with a human face

Concurrency Without Compromise

M:N fiber scheduler. Structured scopes. CSP channels. No function coloring. No runtime bloat.

pipeline.jan :service
// Structured concurrency + CSP channels.
// Every task completes or cancels at nursery end.

async func main() do
  let ch = channel(10)

  nursery do
    spawn producer(ch)
    spawn consumer(ch)
  end  // both tasks guaranteed done here
end

func producer(ch: Channel) do
  for i in 0..100 do
    ch.send(i)
  end
  ch.close()
end

func consumer(ch: Channel) do
  while not ch.isClosed() do
    let val = ch.recv()
    println(val)
  end
end
~50ns Task Switch
10K Sessions / 4 Threads
0 Polling Overhead

Structured Scopes

nursery guarantees every spawned task completes or cancels before the scope exits. No orphaned goroutines. No forgotten futures. The compiler enforces the lifetime.

No Function Coloring

No async/await viral infection. Sync and async code share the same grammar. The scheduler decides; the programmer writes intent.

CBC-MN Scheduler

Capability-Budgeted Cooperative M:N with work-stealing. Fibers multiplex over OS threads. The main thread participates as a worker – zero wasted cores.

vs. Go

Task lifecyclenursery (scoped)goroutine (fire-and-forget)
Orphan preventioncompiler-enforcedmanual / errgroup
Channelstyped + selecttyped + select
SchedulerM:N work-stealingM:N work-stealing

vs. Rust

Function coloringnoneasync fn required
Runtimebuilt-in (5.2K LOC)external (tokio ~70K)
Structured scopesnursery (first-class)tokio::spawn (unstructured)
Pin complexitynonePin<Box<dyn Future>>

Not Promises. Proofs.

Everything listed here compiles, runs, and is tested. Today.

Full Trait System

Traits, impl blocks, static + dynamic dispatch with vtables. Fat pointers for &dyn Trait. Default methods. Complete polymorphism system.

Structured Concurrency

Nurseries, spawn, await, select, channels. M:N fiber scheduler with 5,249 lines of battle-tested runtime. CSP done right.

🔍

Queryable AST Database

Code stored as a semantic database with content-addressed identity. AI and tooling can query structure, not parse text. UUID-stable refactoring.

🛡

Error Unions

T ! E error types, fail, catch, try. Errors are values, not exceptions. The type system tracks what can fail.

🌀

Closures

Zero-capture, captured, mutable capture. Three clean closure types with explicit capture semantics. No hidden allocations.

🔗

One Language, Two Faces

Janus compiles through Zig – not to it, not beside it. use zig and you write Janus syntax with Zig’s type system, crypto, I/O, and allocators. No FFI. No bindings. Same binary. Ed25519 in do..end blocks.

Comptime Primitives

comptime do...end blocks, §size_of/§type_info compile-time sigil builtins, inline for/inline switch. Checked arithmetic, resource-limited evaluation. Profile-gated — :core gets basics, :service gets introspection. The § sigil is the canonical form for compile-time evaluation.

💾

Memory Authority

Buffer, OwnedSlice[T], and Arena make ownership explicit in the type system. Every allocator is visible, every destructor is explicit. No hidden deallocators, no ambient allocators. The type says what owns memory.

Pattern Matching

match on integers, enums, tagged unions. Exhaustiveness checking. The right arm fires; the rest don't exist.

📦

Generics + Multi-Dispatch

Monomorphized generics. Scoped Impl Resolution — no orphan rules. Julia-style multi-dispatch on ALL arg types. 13K LOC dispatch engine.

SBI Wire Format

Sovereign Binary Interface — zero-encoding where wire = memory. Decode is a pointer cast, not deserialization. BLAKE3 Merkle proofs for field-level verification. Comptime schema fingerprinting. No protoc, no IDL, no codegen.

🔒

Hinge Package Manager

Sovereign supply chain. Ed25519 + Dilithium3 hybrid signatures, BLAKE3 content addressing, Chapter federation, witness consensus, trust graphs, DMP gossip, transparency ledger. 25 modules, 18K LOC.

📜

Self-Documenting ASTDB

Documentation is data, not decoration. /// comments are parsed into structured columnar arrays — queryable by predicate. janus doc generates Markdown. janus query --doc finds undocumented, deprecated, or incomplete declarations. Docs survive renames via CID identity.

janus fmt

Canonical formatter. One style. No arguments. janus fmt file.jan formats in-place; --check mode exits non-zero with a line-by-line diff for CI. 34 idempotency-verified tests. Dogfooded on 1,000+ line production code. A language without fmt tolerates arguments about whitespace. Janus doesn’t.

"A language is not a tool. It is a discipline."
— Janus Zen, Doctrine I

Mutable Value Semantics, Forged for Sovereign Systems.

Janus credits Hylo’s lineage honestly, then carries the model into actors, profiles, tensors, and the sovereign stack.

Janus stands on serious shoulders.

Janus did not invent Mutable Value Semantics from nothing. Hylo, formerly Val, pushed this design space into serious language-theory territory: value-oriented programming, mutation without spooky action at a distance, compiler-enforced exclusivity, and function parameters that describe intent instead of exposing references.

Dave Abrahams, Dimi Racordon, and the Hylo team proved the core thesis: you can keep local reasoning and still mutate in place. You can move borrow reasoning out of the programmer’s hands and into the compiler, where it belongs.

The programmer should describe the deed. The compiler should build the bridge.

Intent, not machinery.

view — read this
edit — mutate this
take — consume this
make — initialize this

Hylo expresses Mutable Value Semantics through let, inout, sink, and set. Janus proposes its own surface for the same moral center: function signatures state intent, not ABI machinery.

🧬

Hylo is the academic flagship.

Hylo validates the paradigm: Mutable Value Semantics, projections instead of exposed references, and compiler-side exclusivity. Janus cites the lineage instead of pretending the idea fell from orbit.

Janus extends the battlefield.

Reference capabilities, affine resources, actors, profile-gated semantics, tensor descriptors, and raw pointer preservation at FFI boundaries. Same foundation; different war.

🔒

The borrow checker moved.

The analysis still exists. The compiler must prove exclusivity and reject unsafe aliases. What disappears is the programmer’s obligation to write lifetime riddles by hand.

Janus did not make the borrow checker nicer.
It made the programmer’s borrow checker unemployed.

Mutable Value Semantics for sovereign systems programming.

Rust Covers Memory. Janus Tracks Eight Axes.

A systems language should not merely prevent use-after-free. It should expose the whole operational surface: what code may mutate, share, touch, consume, allocate, authorize, terminate, and replay.

Axis Janus mechanism Compiler-visible question
MemoryMutable Value SemanticsWhat does this function do with each value?
ConcurrencyReference capabilities + nurseriesWho may share, send, mutate, or isolate data?
Side effectsAlgebraic effect rowsWhat world-contact can this call graph perform?
AuthorityResource capabilities + manifestsWhich resources may this binary touch?
TerminationTotal functionsDoes this computation finish on all paths?
PreconditionsRefinement typesWhat must be true before this value is valid?
Compile-timeComptime trichotomy + comptime effectsWhat runs during build, and with what authority?
DeterminismDeterministic effect disciplineWill the same inputs produce the same outputs under replay?

This is the Janus thesis: Rust proved programmers would accept compiler-enforced discipline for memory. Janus asks the obvious next question: why stop there? Read the full thesis →

No Fantasy. Just Facts.

Green where we deliver. Red where we don't. Yet.

Feature Janus Go Rust Zig
Trait System Traits + impl, static + dynamic dispatch Interfaces Traits + impls Duck typing
Generics Monomorphized — identity[T] compiles natively Since Go 1.18 Full generics + traits Comptime generics
Multi-Dispatch Julia-style — resolves on ALL arg types Single dispatch only Single dispatch (self only) No dispatch system
Scoped Impl Resolution No orphan rules — 5-stage SIR pipeline No trait system Orphan rule restricts impls No trait system
Structured Concurrency Nurseries — no orphan tasks Goroutines leak freely tokio::spawn is unstructured Has async frames
Error Handling Error unions T ! E if err != nil boilerplate Result<T,E> + ? operator Error unions + try
Syntax Clarity do/end blocks, clean grammar Simple but verbose Lifetime annotations, turbofish Comptime complexity
Native Compilation LLVM via Zig toolchain Go compiler LLVM LLVM + self-hosted
Zig Stdlib Access native — one compilation unit, not FFI CGo overhead Separate FFI Native
Enum/Union Types Tagged unions + match No sum types enum + match Tagged unions
Compile-Time Evaluation comptime blocks, $builtins, inline for/switch No comptime const fn (limited) Full comptime
Sovereign Packages Hinge — signed, federated, post-quantum go mod (centralized) crates.io (centralized) No package manager
Binary Wire Format SBI — zero-encoding, BLAKE3 Merkle proofs protobuf (varint encode/decode) serde (ecosystem, not built-in) No standard wire format

Janus v2026.3.23 — :core + :service profiles complete. janus fmt canonical formatter. janus build reads lockfile and compiles dependencies. Hinge sovereign package manager with full local lifecycle. One Language, Two Faces: Janus syntax fused with Zig’s type system and stdlib in a single compilation unit. No FFI. No bindings. Multi-dispatch, scoped impl resolution, trait-bounded generics, sovereign federated packages, and queryable documentation are unique to Janus.

SBI vs. The Serialization Zoo

Fixed-size structs, same architecture. Zero encoding. Zero parsing. Zero copies.

Dimension SBI SSZ Protobuf FlatBuffers Cap'n Proto
Encode Cost Zero (memcpy identity) LE pack + offsets Varint encode per field Vtable + buffer build XOR + offset calc
Decode Cost Pointer cast (O(1)) Offset walk Full varint decode Vtable lookup Deref + XOR
Wire = Memory Exact identity Packed, no alignment Varint encoding Structs only (LE) Nearly (XOR defaults)
Merkle Proofs BLAKE3, field-level SHA-256, generalized None None Flat hash only
External Tooling None — compiler is schema None (implicit) protoc + plugins flatc + plugins capnpc + plugins
Schema Evolution None (by design) None formal Field numbers Tables only Append-only
Variable-Length Data Planned (:service) Offset tables LEN wire type Vectors, strings Lists, text
Language Support Janus + Zig ~8 (Ethereum) 30+ languages 14+ languages ~16 languages

SBI is not a general-purpose serialization framework. It is the fastest possible wire format for a constrained domain: same-architecture peers, fixed-size structs, cryptographic type identity. Schema evolution and variable-length data trade correctness for flexibility — SBI chooses correctness. Full SBI documentation →

Field Note / Language Positioning

When The Sovereign Becomes A Founder

Why Bun's Rust rewrite matters, and why the next systems language cannot choose between Zig's trust and Rust's ceremony.

By Voxis Forge — Janus desk. Filed from Budapest.
A neon construction site split between raw systems craft, safety scaffolding, and a Janus compiler gate.

The Tweet That Lit The Discourse

On May 9th, 2026, Jarred Sumner, creator of Bun, posted one sentence that detonated across systems-programming Twitter:

"99.8% of bun's pre-existing test suite passes on Linux x64 glibc in the rust rewrite."

Bun, the flagship Zig-in-production exhibit. The language's most visible commercial success. The "look, Zig ships at scale" demo every Hacker News thread cited for two years.

Experimenting with a Rust rewrite serious enough to run the existing test suite against it.

Not a final migration decree. Not an irreversible public commitment. But serious enough that he is running the existing test suite against a Rust implementation and publishing the pass rate.

The discourse, predictably, lost its mind.

The Rust crowd treated it like a coronation. The Zig crowd treated it like betrayal. Both reactions are noise. Both miss the only signal in this story that actually matters.

We will not speculate on Sumner's specific reasoning. The man can speak for himself, and has. What matters here is the archetype: the moment the sovereign individual becomes a founder. The earlier public reporting framed the Rust work as exploratory; that caveat makes the signal cleaner, not weaker. The Register covered the same ambiguity.

Two Photographs Of The Same Engineer

Picture a hypothetical engineer in solo founder mode. Brain on fire, fingers on keys, building a runtime from nothing. They pick Zig because Zig fits their head: every byte visible, every allocator explicit, no compiler trying to parent them through ownership decisions they already understand.

This is the engineer-as-craftsman. Zig serves them perfectly. Their relationship is a love story written in errdefer and arena resets.

Now picture the same engineer in company mode. The runtime has employees, a roadmap, customer commitments, and an on-call rotation. The codebase crossed the threshold where one brain can no longer hold the whole architecture at once. New engineers ship code into it every week. Some are excellent. Some are learning. Most are strong in the runtime's domain and merely adequate at low-level memory discipline.

Zig assumes the engineer reading the docs is the engineer writing the code. At a thirty-person company, that assumption breaks every Tuesday morning at standup.

The junior forgets defer on the wrong path. The mid-level engineer ships a toOwnedSlice() whose ownership semantics he half-understood. The senior catches it late. The CTO watches production memory climb and asks the question every founder eventually asks:

What language would have caught this at compile time instead of in production?

For many founders, the answer is Rust. Of course it is. Rust converts large classes of dangling-reference, use-after-free, and data-race discipline from a cultural property of the team into a mechanical property of the compiler. It does not prove leak-freedom; Rust itself documents reference cycles as memory-safe leaks.

The Two Kingdoms

Zig is a tool for sovereign individuals. Engineers who already know what allocator-threading means. Engineers who understand that errdefer cleans partial construction. Engineers who can hold the lifetime of a returned slice in their working memory while reviewing the API shape.

Zig assumes you graduated kindergarten. It refuses to walk you to the bathroom. If you wet yourself in production, that is between you and your god.

Rust is a tool for teams that cannot make that assumption. The borrow checker exists because at any sufficiently large company, someone on the team is going to mishandle ownership, and you would prefer that someone be a compiler error instead of a CVE.

Zig says: "You own the bytes. Don't be stupid."
Rust says: "Prove to the priesthood you are not stupid."

Both positions are coherent. Both are correct for their target population. The problem is that neither population is the team that exists at a successful Series B startup.

  • Two senior engineers would be happy in Zig and find Rust insulting.
  • Five mid-level engineers could go either way but appreciate the safety net.
  • Eight junior engineers know the domain and are still learning memory discipline.
  • One staff engineer just wants the on-call rotation to stop catching fire.

Zig serves the seniors and abandons the rest. Rust serves the rest and forces the seniors to file paperwork in triplicate every time they want to write something obvious.

That decision is not a victory for Rust. It is a defeat for both languages. Because the right answer was never on the menu.

Allegory Time: The Construction Site

Imagine you are building a skyscraper.

Zig is the philosophy of master craftsmen. Every worker on the site is a thirty-year veteran. No signs, no fences, no safety equipment. Why would there be? Everyone here knows where the edges are.

Then the project gets big enough that you hire fifty more workers. Some are veterans. Most are not. The site has no signs. They start falling off the third floor.

Rust is the philosophy of OSHA. Everyone wears the harness. Every beam has a rating. Every tool has a certification. Veterans grumble. Productivity drops. Nobody falls.

Now ask the language-design question: what if the site could have signs that experienced workers can ignore, and that warn juniors exactly where the danger is? What if harnesses were optional in low-risk zones and mandatory in high-risk zones? What if safety was adaptive to the worker and the work instead of one uniform policy everywhere?

That site does not exist in the language landscape today. Rust is uniform-everywhere OSHA. Zig is no-OSHA-anywhere. Janus is being built as the third site.

What Each Language Actually Promises

LanguageWhat it promisesWhat it does notCognitive tax
CYou can do anything.Memory safety, type safety, pretty much any safety.Zero, until production.
C++You can do anything, plus safety nets if you remember them.Coherence between safety nets.Variable, hidden, weaponized at code review.
ZigAllocation is visible. Errors are visible. You own the bytes.Compile-time enforcement of ownership discipline.Zero for veterans, infinite for juniors.
RustSafe Rust prevents large classes of dangling-reference, use-after-free, and data-race bugs.Ergonomic ownership, cycle-leak freedom, sane async.Constant, uniform, paid by everyone.
GoGarbage collection. Goroutines. Ship it.Performance predictability and real systems control.Low, paid in latency tails.

Now look at what nobody promises: memory discipline visible at the boundaries that matter; compile-time ownership proof without user-facing lifetime annotations; authority, effects, termination, and determinism tracked under one doctrine; junior-safe defaults with senior-controllable escape hatches.

That list is the gap.

Janus: What We Built From The Wreckage

Janus did not start from "what would be cool to add to a language." It started from cataloguing where Zig forces sovereign individuals to perform discipline manually, and where Rust charges teams cognitive rent for guarantees the seniors do not need.

The result is the Eight Axes of Provability. Janus is being designed around eight orthogonal compile-time questions — some already specified, some in implementation, some still under formal audit — that the language lets you express only when relevant:

AxisJanus mechanismRust equivalentZig equivalent
Memoryview / edit / take / make intents&T, &mut T, lifetimesManual allocator and ownership discipline
Concurrencyiso / val / ref / tagSend + SyncManual discipline
Side effects!{IO, Net, Alloc} rowsNoneNone
AuthorityCapability tokens + manifestsNoneNone
Terminationtotal funcNoneNone
Preconditionswhere predicatesNewtype patternsRuntime asserts
Compile-time§{}, comptime, !{Comptime}const fn + macroscomptime
DeterminismEffect absence + replay disciplineNoneNone

Eight axes. Most functions use one or two. Some use zero. The eight-axis architecture is not a tax. It is a vocabulary. You only pay for what you express.

The Specific Move: Scoped Allocation Blocks

The operational pain that makes allocator-threading a death march at thirty engineers is solved by one Janus mechanism: lexical arena scopes that handle the Alloc effect.

Zig:

pub fn handle_request(allocator: std.mem.Allocator, socket_data: []const u8) !Response {
 const req = try parse_request(allocator, socket_data);
 defer req.deinit(allocator);

 const route = try match_route(allocator, req.path);
 defer route.deinit(allocator);

 const response = try handle_route(allocator, route, req);
 errdefer response.deinit(allocator);

 try write_response(allocator, response);
 return response;
}

Allocator threaded four times. Three defers. One errdefer. Every junior who touches this is one missed cleanup away from production bloat.

Rust:

fn handle_request<'a>(socket_data: &'a [u8]) -> Result<Response<'a>, HttpError> {
 let req = parse_request(socket_data)?;
 let route = match_route(&req.path)?;
 let response = handle_route(&route, &req)?;
 write_response(&response)?;
 Ok(response)
}

Looks clean. Now write the real version. Lifetimes propagate through the response, the error type crosses boundaries, and the senior starts filing paperwork.

Janus:

arena {
 name: req_arena,
 backing: heap,
 capacity: 16.kib,
} do
 let req = parse_request(socket_data)?
 let route = match_route(req.path)?
 let response = handle_route(route, req)?
 write_response(response)?
 return response
end
// arena released; every allocation freed at the boundary

One arena declaration at the work-unit boundary. Functions inside declare !{Alloc}; the arena handles it. The compiler proves no arena-backed value escapes the arena lifetime.

Function declares the need. Caller declares the jurisdiction. The compiler proves the contract.

The AI Migration Shadow

There is another signal under this story: AI-assisted translation. A runtime-scale codebase pushing deep into a language rewrite is not merely a Rust story. It is a toolchain story. Languages now compete not only on human ergonomics, but on how well agents can read, transform, verify, and repair them.

That does not weaken the memory thesis. It sharpens it. A language for the next decade must be legible to humans and agents, with invariants visible enough that both can preserve them under transformation.

What Janus Is Stealing, And What Janus Is Refusing

Good language design is the discipline of stealing the right things and refusing the wrong things.

Stolen from Zig: allocator visibility, defer, comptime, no hidden allocation, errors as values.

Stolen from Hylo: Mutable Value Semantics; the programmer expresses intent, the compiler chooses lowering.

Stolen from Pony and Erlang: capability-shaped actor discipline.

Stolen from OpenBSD: pledge and unveil as syscall-surface narrowing.

Refused from Rust: lifetime annotations, the borrow checker as user-facing ritual, async function coloring.

Refused from Zig: programmer-discipline-only memory safety where teams need compiler enforcement.

Refused from everyone: garbage collection as a default memory model. :script gets an execution-scoped arena, not a tracing collector. Convenience does not require amnesia. Ambient reference counting, external theorem-prover dependencies, and ambient filesystem/network/time authority are refused too.

The refusal list is longer than the steal list. That is intentional. Most language designs sin by addition. Janus adds only where subtraction would cost more.

The Pitch, Stripped

If you are a sovereign individual building solo and Zig fits your head: keep using Zig. Janus will be there when your project becomes a company.

If you are at a Rust shop and the borrow-checker fights drain your team's cognitive budget: Janus is being built for you.

If you are watching a team-scale runtime project pivot to a language nobody really wanted to migrate to but had no other option: we are building the language we wished existed earlier.

It is not ready yet. The eight-axis architecture is locked. The implementation is staged and deliberately audited. The native prover roadmap exists because importing sovereignty from someone else's cathedral is not sovereignty.

But here is the thing nobody else in the systems-language space can say: we know exactly what we are building, why we are building it, and what we refuse to build.

The Closing Bell

Bun is moving serious work toward Rust because the language Sumner loved may not scale to the company he built. That is not a Zig failure. That is Zig being honest about its target audience.

Rust catches the migration because the language was designed for exactly this transition. That is not a Rust victory. That is Rust paying the cognitive tax that Zig refused to charge.

The real story is not which language won. The real story is that the language we actually wanted did not exist.

A language where the senior keeps her bare-metal control. Where the junior gets compiler-enforced safety. Where memory discipline is visible at the boundaries that matter and invisible where it does not. Where allocation, authority, effects, termination, and determinism are tracked under one doctrine instead of stitched together from third-party crates.

Zig says: "Don't be stupid."
Rust says: "Prove you are not stupid."
Janus says: "Declare what you mean. The compiler proves the rest. You can bring your juniors."

The construction site has signs now. Veterans can ignore them. Juniors can read them. Nobody falls off the third floor.

Lexical arena scopes are an active design direction, not a ratified surface. The doctrine is the point: allocation honesty, not hidden memory magic.

Clone. Build. Run.

You know the drill. Requires Zig 0.16.x.

terminal
# Clone and build (requires Zig 0.16.x)
git clone https://git.sovereign-society.org/janus/janus-lang.git
cd janus-lang && zig build

# Scaffold a new project
./zig-out/bin/janus init myproject
cd myproject

# Build and run
../zig-out/bin/janus build src/main.jan main && ./main
# "Hello from Janus!"

# 1,700+ tests passing
zig build test

Honest Status. No Hype.

Green means working code with passing tests. Yellow means specified. Blue means dreamed.

Compiler Pipeline

Tokenizer + Parser
ASTDB (regions, CID, schema)
Semantic Analysis
QTJIR (SSA IR)
LLVM Codegen
Dispatch Engine (13K LOC)

Language Features

Traits + Impl (static + dynamic)
Closures (3 capture types)
Enums + Tagged Unions
Structured Concurrency
Error Unions + Optionals
Generics (monomorphized)
Comptime Primitives

Ecosystem

30K LOC Standard Library
Hinge (25 modules, 18K LOC)
DMP Gossip Broker
janus init (scaffolding)
LSP Server (early)
janus doc + query --doc
janus fmt

Profiles

:core (100% complete)
:service (100% complete)
:script (shipping — v2026.4.8)
:cluster
:compute (native trig + polar)
:sovereign