Janus grows teeth: capabilities, effects, storage, and introspection
Junior Dev Nugget; principle: A compiler feature is not real when it parses. It becomes real when the pipeline can observe it, reject lies about it, and make it queryable.; likely mistake: Mistaking syntax for enforcement. A keyword that does not affect checking, lowering, runtime shape, or diagnostics is decorative paint.; read next: The public Janus docs on effects, capabilities, and the eight axes of provability.
What changed
Janus had another heavy trench day.
Four things advanced at once:
-
Capabilities moved closer to runtime reality. The manifest story is no longer just a front-door declaration. The compiler and runtime path now carry more of the shape needed to materialize declared authority instead of pretending that a comment in a config file is a security boundary.
-
Effects became more inspectable. The language work around declared side effects gained more machinery for tracking what functions claim, what bodies actually do, and what the compiler can ask later. This matters because Janus is not trying to make side effects morally pure. It is trying to make them visible.
-
The compiler learned more about the program as a graph. Module-level function discovery and query output improved. That sounds boring until you remember what an agent-readable language needs: not just code that compiles, but code whose structure can be queried, indexed, reviewed, and repaired by tools without archaeological guesswork.
-
The storage layer kept hardening. The LSM path advanced through compaction, recovery, cached metadata, and a nasty cross-module field-layout defect. That last one matters: the bug was not glamorous. It was the compiler misunderstanding a foreign-typed struct field enough that a chained field access collapsed later. Exactly the kind of quiet structural lie that destroys trust if you let it survive.
The theme is simple: Janus is turning promises into surfaces the compiler can interrogate.
Why this now
The project is crossing a boundary.
Early language work proves syntax. Mid-stage language work proves invariants. Janus is now spending more of its energy on the second category.
A capability promise must become runtime shape. An effect row must become graph data. A module must become queryable structure. A storage engine must survive reopen, recovery, and compaction without relying on heroic memory of what the previous call did. A compiler must preserve qualified names and foreign field shapes because one missing piece of name recovery can turn a real type into an integer-shaped hallucination.
This is not feature theater. It is infrastructure becoming less gullible.
Design decisions and tradeoffs
-
Chosen path: keep effects visible across the language surface. Profiles should change what handlers exist by default, not whether the language admits the concept. A student should not learn one language in script mode and another one in service mode.
-
Chosen path: make capabilities flow through explicit declarations and runtime materialization. Authority is not a vibe. It has to come from somewhere, be narrowed somewhere, and be inspectable somewhere.
-
Chosen path: make program structure queryable. Tooling, agents, documentation, and audits all get stronger when the compiler can answer structural questions directly.
-
Chosen path: push storage through boring failure modes. Open, recover, compact, cache metadata, and then test the weird edges. Storage does not become real because the happy path writes bytes. Storage becomes real when the reopen path still tells the truth.
-
Rejected path: raw internal report publication. The public devlog should explain what changed and why it matters. It should not leak the operating map.
The Junior Dev Nugget
- The principle being demonstrated: parsing is not enforcement.
- The mistake the reader would have made: celebrating a syntax feature before checking whether it affects analysis, lowering, runtime shape, diagnostics, or tests.
- What to read or look at next: read the public docs on effects and capabilities, then ask which parts are syntax, which parts are analysis, and which parts survive into runtime behavior.
A compiler is a chain of custody. If a fact enters at the source surface but disappears before verification, it was never a fact. It was decoration.
Ideological stance, grounded
Sovereign systems need compilers that do not shrug.
If a program says it needs authority, the compiler should ask where that authority comes from. If a function says it performs an effect, the compiler should make that claim visible. If a module contains callable structure, tools should not need regex archaeology to find it. If storage claims durability, it must keep its story straight after restart and compaction.
This is the Janus line: hidden obligations become explicit structure; explicit structure becomes compiler evidence; compiler evidence becomes operational trust.
That is what separates a sovereign toolchain from a pile of optimistic conventions.
References
- Public Janus documentation on effects and capabilities.
- Public Janus philosophy on the eight axes of provability.
- Public Janus release and tutorial surface.
This report intentionally omits internal paths, private branch names, internal report filenames, specification numbers, diagnostic codes, and commit receipts.
What comes next
The next public signal should come from one of three lanes:
- the capability runtime path becoming easier to demonstrate end-to-end;
- the effect graph becoming useful to users instead of only compiler engineers;
- the storage layer proving a clean recovery-and-compaction story that can be explained without internal scaffolding.
Until then, the lesson is already visible: Janus is no longer just adding language surfaces. It is teaching the compiler to remember what those surfaces mean.
— V.