v2026.7.3: Representation & Layout Doctrine (SPEC-246)
v2026.7.3: Representation & Layout Doctrine (SPEC-246)
Section titled “v2026.7.3: Representation & Layout Doctrine (SPEC-246)”Janus now has a constitutional answer to a question most languages leave
implicit: what does a struct mean in memory, and who decides?
The answer is layered, explicit, and proven by the compiler — not folded into a keyword.
A
structdefines what fields exist.@layout(...)defines how they’re stored.@repr(...)defines how each field is encoded. Those are three different questions, and Janus keeps them apart.
See Representation & Layout for the full reference; this note covers what changed and why.
What’s new
Section titled “What’s new”1. Layout profiles via @layout(...)
Section titled “1. Layout profiles via @layout(...)”A struct’s physical organization is now selected by an attribute, not a keyword:
| Profile | Use |
|---|---|
stable (default) | deterministic, correctness-preserving — most structs |
optimal | opt-in compiler optimization (Rust-style reordering) |
wire | architecture-independent binary contract (SSTable, SKV, SBI, protocols) |
packed | exact density, no padding |
c | C ABI (FFI) |
simd / cacheline | hardware alignment |
opaque | intentionally unknowable (handles, runtime internals) |
A struct with no @layout(...) is @layout(stable). That default is
chosen on failure-mode asymmetry grounds: forgetting an optimization
shows up in a profiler, forgetting a binary contract shows up in
production.
2. WireSafe — a compiler-derived proof
Section titled “2. WireSafe — a compiler-derived proof”A struct declared @layout(wire) may be proven WireSafe — the
compiler certifies it has a fixed layout, no process-local ownership,
no pointers, and exactly one canonical byte representation per
value. There is no unsafe impl WireSafe. If the compiler can prove
it, it does; if it can’t, you get a precise diagnostic and the answer
is “express the design differently” (use a codec, not a type lie).
The Canonical Representation Principle unlocks a remarkable
consequence: for T: WireSafe, equality, hashing, serialization,
disk-mapping, and fingerprinting all derive from one canonical byte
sequence. a == b may lower to memcmp. hash(a) is BLAKE3 of
canonical bytes. socket.write(&value) needs no serializer.
3. extern struct is deprecated
Section titled “3. extern struct is deprecated”The historical extern struct Foo { ... } is now parser sugar that
the compiler rewrites during parsing to:
@layout(c)@repr(native)struct Foo { ... }After parsing, the frontend never sees extern struct — there is
exactly one semantic representation of layout in the AST. Compiling
extern struct emits:
W1204: `extern struct` is deprecated.
Use: @layout(c) struct Foo
`extern struct` is a parser alias for `@layout(c) @repr(native)` andwill be removed in Janus 2.0.Existing source keeps compiling. Migrate when convenient. The deprecation follows a general policy we’re naming for the first time:
Syntax Evolution Doctrine — language evolution preserves semantics before syntax. Old syntax parses; the compiler lowers to the new semantic form; warnings educate; a later edition removes the obsolete syntax.
Why not just keep extern struct?
Section titled “Why not just keep extern struct?”Because keeping it as a parallel grammar path reintroduces exactly the
problem SPEC-246 solves. Today @layout(...) is the one place layout
lives. If extern struct survived, eventually someone would want
extern packed struct, extern simd struct, extern cacheline struct
— a new keyword every time a new representation policy appears. The
attribute system absorbs all of them without touching the grammar.
Why stable as the default (not optimal / Rust-style)
Section titled “Why stable as the default (not optimal / Rust-style)”Two arguments, in priority order:
- Failure-mode asymmetry. A forgotten optimization is observable in a profiler. A forgotten correctness boundary (wire format, ABI) is observable six months later in production. A language for capability-safe kernels and protocols should default to the correctness-preserving failure mode.
- Domain fit. Janus’s target domain — databases, protocols, zero-copy, sovereign kernels — spends more time at the systems boundary than Rust’s. Stable layout is the more valuable default there. (But argument 1 is load-bearing; argument 2 is supporting.)
Three constitutional principles
Section titled “Three constitutional principles”This SPEC elevates four principles to sit alongside ownership, effects, capabilities, and profiles:
The Implicit-Contract Principle — implicit facts are acceptable if mechanically derivable from explicit declarations; implicit contracts are not. (Justifies auto-derived
WireSafe; rejects hidden ABI.)
The Representation-Orthogonality Principle — “what fields exist?” and “how are they stored?” must not be conflated.
The Canonical Representation Principle — a value in a declared binary contract has exactly one valid in-memory representation. Padding, inactive-union payloads, and NaN payloads are not distinct valid representations.
The Representation-is-a-Type-Property Principle — representation is a property of the type, not a property of serialization. Serialization, hashing, equality, and fingerprinting derive from the type’s representation; they do not define it. This is what distinguishes Janus from Rust, Zig, C, Swift, Go, and most serialization frameworks.
What’s next
Section titled “What’s next”- Layer 1 (compiler): parser rewrite of
extern struct,@layout(...)attribute parsing, WireSafe derivation pass, the new diagnostics (E2301–E2306,E2412–E2413,W1204). - Layer 4 (monastery): teaching material on layout profiles and
WireSafe; mission updates for any mission using
extern struct. - Future (v0.2): wire-layout-change fingerprinting diagnostic;
composable
@layout { ... }; configurable canonical NaN.
Migration cheat sheet
Section titled “Migration cheat sheet”| Before | After |
|---|---|
extern struct Foo | @layout(c) struct Foo |
extern struct Foo (BE protocol) | @layout(c) @repr(network) struct Foo |
wire-format extern struct Foo | @layout(wire) @repr(network) struct Foo (and prove WireSafe) |
The third row is a semantic upgrade, not a mechanical edit: moving a
type to @layout(wire) commits it to a binary contract and triggers
the WireSafe proof. Use it for types that genuinely cross persistence
or network boundaries.
Developed with Voxis Forge assistance over a four-turn design
conversation; ratified as Position A+ (Canonical Representation) per
Founder decision 2026-07-03. Operational spec: .agents/specs/_PROPOSED/SPEC-246-representation-and-layout-doctrine.md.