kae3g 9503: What Is Nock? Specification Language for Sovereign Systems
Phase 1: Foundations & Philosophy | Week 1 | Reading Time: 18 minutes
What You'll Learn
- Nock: A minimal computation function reduced to 12 rules
- Why specification languages matter for system design
- How Nock could specify sovereign operating systems
- Nock as mathematical foundation for microkernel design
- The bridge between formal verification and practical systems
- Why minimalism enables century-long software
- Connection to seL4, RISC-V, and the valley's sovereignty vision
Prerequisites
- 9500: What Is a Computer? - Turing machines, universality
- 9501: What Is Compute? - Distributed computing, sovereignty
Helpful context:
- 9948: Why We Love Computers - Emotional foundation
- 9507: Helen Atthowe - Living systems thinking
The Specification Problem
Imagine designing an operating system that should last 100 years:
Problem: How do you specify what it should do?
Most OS specifications:
- POSIX: 3,700 pages (ambiguous, complex)
- Windows API: Undocumented internals, constantly changing
- Linux: "The implementation IS the specification" (20+ million lines)
Result:
- Bugs (undefined behavior everywhere)
- Incompatibilities (different interpretations)
- Bit rot (specifications drift from reality)
- Impossible to verify (too complex to prove correct)
What if you could specify an entire OS in 12 rules?
That's Nock.
What Is Nock?
Nock is a combinator calculus: a pure function from noun to noun.
Translation:
nock(subject, formula) → product
Input: Two pieces of data (subject, formula)
Output: One piece of data (product)
That's it. The entire specification.
Nouns: The Only Data Type
A noun is:
- An atom (unsigned integer, any size):
0
,42
,2^256
- A cell (pair of nouns):
[a b]
Examples:
Atom: 17
Cell: [4 5]
Nested: [[1 2] 3]
List-like: [1 [2 [3 0]]]
Everything is nouns: Programs, data, operating system state, all nouns.
Plant lens: Nouns are like cells (atoms = simple cells, pairs = tissue).
The 12 Rules (The Entire VM)
Don't memorize—just appreciate the radical minimalism:
Nock 4K Specification (12 reduction rules):
?[a b] 0 # cell test (yes)
?a 1 # atom test (no)
+[a b] +[a b] # increment crashes on cell
+a 1 + a # increment atom
=[a a] 0 # equality (yes)
=[a b] 1 # equality (no)
/[1 a] a # tree addressing: root
/[2 a b] a # left branch
/[3 a b] b # right branch
/[(a + a) b] /[2 /[a b]] # even: recurse left
/[(a + a + 1) b] /[3 /[a b]] # odd: recurse right
*[a [b c] d] [*[a b c] *[a d]] # nock of cell
*[a 0 b] /[b a] # slot
*[a 1 b] b # constant
*[a 2 b c] *[*[a b] *[a c]] # nock (recurse)
*[a 3 b] ?*[a b] # cell test
*[a 4 b] +*[a b] # increment
*[a 5 b c] =*[a b] *[a c] # equality
*[a 6 b c d] *[a *[[c d] 0 *[[2 3] 0 *[a 4 4 b]]]] # if
*[a 7 b c] *[*[a b] c] # compose
*[a 8 b c] *[[*[a b] a] c] # extend subject
*[a 9 b c] *[*[a c] 2 [0 1] 0 b] # call
*[a 10 [b c] d] #[b *[a c] *[a d]] # hint
*[a 11 [b c] d] *[[*[a c] *[a d]] 0 3] # static hint
*[a 11 b c] *[a c] # dynamic hint
That's the entire virtual machine.
Compare:
- x86-64: 1,000+ instructions, 5,000-page manual
- RISC-V: 47 base instructions (excellent!), but still >12
- WASM: 170+ instructions
- Nock: 12 rules, 2 pages
Why This Matters for System Design
The Complete Sovereignty Stack
Vision (from the valley's architectural plan):
Your Sovereign System:
↓
Userspace Applications (Clojure + Nix)
↓ optimized by
GraalVM/TruffleVM (polyglot, JIT-optimized)
↓ reimplemented using
Nock as specification (abstraction layers provably correct)
↓ running on
Formally Verified Microkernel (seL4-style)
↓ specified in
Nock (12 rules - provably correct)
↓ executing on
RISC-V (open hardware)
↓ maintained via
Grainhouse Strategy (forked dependencies, total sovereignty)
Why Nock at MULTIPLE layers?
Layer 1: Kernel Specification
- Specification → Verification → Implementation
- Write OS behavior in Nock (12 rules = formal spec)
- Prove Nock spec correct (manageable size)
- Implement in C/Rust (with proven correspondence)
- Auditable (security)
- 12 rules = you can audit the entire foundation
- Compare: Can you audit Linux? (30M lines)
- Can you audit x86 microcode? (Proprietary!)
- Eternal (longevity)
- Nock is frozen (never changes)
- Write OS once, runs forever
- No platform churn, no breaking changes
- Portable (sovereignty)
- Nock runs on ANY architecture (x86, ARM, RISC-V, future CPUs)
- Your OS isn't locked to one vendor's chips
- True hardware independence
Layer 2: Userspace Language Runtime
Clojure + Nix as primary userspace languages:
Why Clojure?
- Homoiconic (code as data - like Nock!)
- Immutable data structures (provably correct transformations)
- REPL-driven development (rapid iteration)
- Rich ecosystem (JVM libraries, ClojureScript for frontend)
- Functional paradigm (composable, testable, maintainable)
Why Nix?
- Declarative system configuration (infrastructure as code)
- Reproducible builds (bit-for-bit identical)
- Atomic upgrades/rollbacks (no broken systems)
- Perfect for grainhouse strategy (fork dependencies, maintain forever)
Current limitation: JVM is heavyweight, startup slow.
Solution: GraalVM + TruffleVM optimization!
GraalVM/TruffleVM: Fast Polyglot Runtimes
GraalVM = High-performance JVM with polyglot support
Key innovations:
- Truffle framework: Language implementation framework
- Graal JIT compiler: Aggressive optimization (better than HotSpot)
- Native Image: Ahead-of-time compilation (fast startup, low memory)
- Polyglot: Run multiple languages in same VM (JavaScript, Python, Ruby, Clojure)
Benefits for Clojure:
Standard JVM (HotSpot):
- Startup: 2-5 seconds
- Memory: 50-200 MB baseline
- Warmup: 30 seconds for full JIT
GraalVM (with optimization):
- Startup: 10-50 ms (native image)
- Memory: 5-20 MB baseline
- Warmup: Instant (AOT compiled)
- Performance: 2-10x faster (after warmup)
This makes Clojure practical for CLI tools, system utilities, embedded scenarios.
The Reimplementation Vision
Current state:
Clojure → JVM bytecode → JVM interpreter/JIT → Native code
(complex, unauditable, 500K+ lines)
Proposed sovereignty stack:
1. Nock specification (12 rules)
↓
2. Clojure semantics in Nock (provably correct spec)
↓
3. Optimizing compiler (Nock → efficient native code)
↓
4. Verified runtime (minimal, auditable)
↓
5. seL4 microkernel (formally verified)
↓
6. RISC-V hardware (open ISA)
Goal: Replace JVM's 500K lines with:
- Nock spec for Clojure semantics (auditable)
- GraalVM-style optimization (Truffle-inspired, but Nock-based)
- Verified compiler (Nock spec → native RISC-V)
- Result: Fast, auditable, eternal Clojure
Incremental path:
- Phase 1 (now): Use existing JVM/GraalVM (proven, works)
- Phase 2: Specify Clojure semantics in Nock (research)
- Phase 3: Build Truffle-style optimizer for Nock (performance)
- Phase 4: Verify compiler correctness (formal methods)
- Phase 5: Replace JVM entirely (full sovereignty)
Timeline: Phase 1 (today), Phase 5 (10+ years).
Why worth it:
- Clojure without JVM dependency (sovereignty)
- Auditable language runtime (security)
- Optimizations provably correct (no JIT bugs)
- 100-year Clojure implementation (eternal)
Nock as Specification Language
Traditional approach (Linux, Windows, JVM):
1. Write C/Java code (implementation)
2. Test it (finite cases)
3. Hope it's correct (bugs everywhere)
4. Specification = "whatever the code does"
Nock approach (proposed for sovereign systems):
1. Write specification in Nock (12 rules = formal)
2. Prove specification correct (mathematical proof)
3. Implement in C/Rust/RISC-V (with verified translation)
4. Specification = immutable, auditable Nock code
Example 1: Process scheduling
Traditional (English spec):
Ambiguous! What's "fair"? How exactly does preemption work?"The scheduler should give each process fair CPU time, preempt after 100ms, and prioritize I/O-bound processes..."
Nock spec (pseudocode):
[scheduler-formula
[cpu-time-slice 100-ms]
[fairness-algorithm round-robin]
[preempt-check [0 current-time] [0 slice-start]]
[io-priority-boost 10-percent]]
Example 2: Clojure persistent vector
Traditional (Java implementation):
// 500+ lines of complex array manipulation
class PersistentVector {
Object[] array;
int shift;
// ... complex trie operations
}
Nock spec (mathematical definition):
[persistent-vector
[structure balanced-trie-32-way]
[lookup [index → value] O(log32 n)]
[update [index value → new-vector] O(log32 n)]
[structural-sharing 31/32-reuse-on-update]]
Precise, executable, provable.
The seL4 Connection
seL4 (the world's only formally verified OS kernel):
- 10,000 lines of C
- Proven: no crashes, no memory leaks, no security bugs
- Used in: Military, aerospace, medical devices
The problem: Verification of seL4 took 11 person-years.
The opportunity: If the specification were simpler (Nock's 12 rules instead of C semantics), verification becomes tractable.
Proposed architecture:
1. Nock specification (12 rules)
↓
2. Nock kernel (implements microkernel in Nock)
↓
3. Verified translation (Nock → C or Rust)
↓
4. Efficient runtime (with jets - fast C for verified Nock)
Result: Verified kernel with simple specification (Nock) instead of complex one (C).
Plant lens: Nock is the seed (genetic code), implementation is the plant (grown organism).
Minimalism Enables Verification
Why 12 rules matter:
Verification cost grows exponentially with specification complexity:
Spec Size | Verification Effort |
---|---|
12 rules | Weeks (feasible for small team) |
100 rules | Months (requires experts) |
1,000 rules | Years (major research project) |
30M lines | Impossible (no one can verify Linux completely) |
Nock's minimalism = verification becomes practical.
This is why military/aerospace systems use seL4 (10K lines) not Linux (30M lines).
Extend the logic: Nock (12 rules) → even simpler to verify than seL4!
The RISC-V Analogy
RISC-V philosophy: Minimal instruction set, open standard, extensible.
Base RV32I: 47 instructions (excellent minimalism!)
Nock philosophy: Even more minimal (12 rules), but same spirit:
- Small trusted base
- Open specification
- Extensible (build complexity on top)
- Eternal (frozen foundation)
Together:
Nock (software VM) ←→ RISC-V (hardware ISA)
12 rules 47 instructions
Eternal spec Open standard
Provable Auditable
Portable Vendor-neutral
Both enable: Long-term, sovereign, verifiable systems.
Practical Example: Nock in Action
Tree Addressing
Problem: Access nested data without variable names.
Nock solution: Binary tree addressing by slot number:
Subject: [[4 5] [6 [14 15]]]
Tree structure:
root (slot 1)
/ \
[4 5] [6 [14 15]]
slot 2 slot 3
/ \ / \
4 5 6 [14 15]
slot 4 slot 5 slot 6 slot 7
/ \
14 15
slot 14 slot 15
Access:
/[1 subject] → [[4 5] [6 [14 15]]] (root)
/[2 subject] → [4 5] (left)
/[6 subject] → 6 (left of right)
/[14 subject] → 14 (deep nested)
Why this matters: No variable names = no scope issues, no shadowing, no closures to track.
Perfect for formal verification (simpler semantics).
How Nock Could Specify a Microkernel
Microkernel responsibilities:
- Memory management (virtual address spaces)
- Inter-process communication (IPC)
- Thread scheduling
- Hardware abstraction (devices)
Nock specification (conceptual):
# Memory allocation
[alloc-memory
[size [0 requested-bytes]]
[available-pages [0 free-list]]
→ [new-page-capability]]
# IPC send
[ipc-send
[endpoint [0 target-endpoint]]
[message [0 message-data]]
→ [send-result]]
# Scheduler
[schedule-next
[ready-queue [0 runnable-threads]]
[current-time [0 clock]]
→ [next-thread-to-run]]
Each operation: Pure function (noun → noun).
Benefit: Can prove properties:
- Memory allocation never leaks
- IPC preserves message integrity
- Scheduler is fair
This is the dream: Microkernel specified in 12 rules, then proven correct.
The Grainhouse Strategy Connection
From the valley's final vision (sovereignty architecture):
Grainhouse = Forked dependencies, maintained independently.
Nock fits perfectly:
- Specification never changes (frozen)
- Implementation forkable (open source interpreters)
- No external dependencies (self-contained VM)
- Eternal compatibility (code from 2025 runs in 2125)
Example grainhouse:
~/grainhouse/
├─ nock-vm/ # Your Nock interpreter (C or Rust)
├─ nock-kernel/ # Microkernel specified in Nock
├─ sel4-fork/ # seL4 microkernel (comparison)
├─ riscv-toolchain/ # RISC-V compiler
└─ documentation/ # Every design decision documented
Result: Complete sovereignty (no external dependencies, all auditable).
Hands-On: Understanding Nock
Exercise 1: Noun Construction
Build these nouns:
1. Atom: 42
2. Cell: [7 8]
3. Nested: [[1 2] [3 4]]
4. List: [1 [2 [3 0]]] (like Lisp cons)
Question: How would you represent a string?
Answer: List of character codes:
"hi" → [104 [105 0]]
(104='h', 105='i', 0=end)
Everything is atoms and cells. No special types.
Exercise 2: Simple Nock Evaluation
Evaluate: *[[42 17] 0 2]
Step through:
- Rule:
*[a 0 b]
→/[b a]
(slot addressing) - Apply:
*[[42 17] 0 2]
→/[2 [42 17]]
- Tree address: slot 2 = left branch
- Result:
42
Try: *[[42 17] 0 3]
(answer: 17 - right branch)
Exercise 3: Constant Formula
Evaluate: *[100 1 999]
Step through:
- Rule:
*[a 1 b]
→b
(constant - ignore subject) - Apply:
*[100 1 999]
→999
Insight: Subject (100) ignored. Formula [1 999]
always returns 999.
This is how you return constants (like return 42;
in C).
Why Not Just Use Lambda Calculus?
Good question! Lambda calculus is also minimal.
Lambda calculus:
(lambda (x) (+ x 1)) ; function with variable x
Problems for verification:
- Variable binding (scope, shadowing, closures)
- Substitution (complex to formalize correctly)
- Requires name management
Nock advantages:
- No variables (tree addressing instead)
- No substitution (pure tree transformations)
- Simpler semantics (easier to verify)
Trade-off: Nock is less intuitive (no familiar variable names), but easier to prove correct.
For 100-year OS specification: Correctness > familiarity.
Criticisms and Honest Trade-offs
Nock is not perfect. Let's be clear:
1. "It's Slow"
True. Naive Nock is ~1000x slower than native code.
Solution: Jets (replace verified Nock with fast C when semantics match).
Status: Mature jetting → acceptable performance.
Priority: Correctness > speed (for kernel specification).
2. "Ecosystem is Tiny"
True. ~1,000 developers (vs millions for Linux).
Counter: Early adopters shape the future (Unix was tiny once).
Our position: Use Nock for specification, implement in proven languages (C/Rust).
3. "Unfamiliar"
True. Tree addressing is weird, no variables is alien.
Counter: Specification doesn't need to be familiar—it needs to be correct.
Analogy: Assembly is unfamiliar too, but CPUs use it (it's correct).
The Complete Valley Vision
Our multi-layer synthesis:
Foundation (Hardware → Kernel)
- RISC-V = Open hardware (vendor-neutral, auditable)
- Nock = Specification language (12 rules, eternal)
- seL4-style kernel = Verified microkernel (specified in Nock)
Runtime (Userspace Languages)
- Clojure = Primary application language (homoiconic, functional, practical)
- Nix = System configuration language (declarative, reproducible)
- GraalVM/Truffle = High-performance runtime (today's optimization)
- Nock-based compiler = Future reimplementation (auditable, verifiable)
Strategy (Independence)
- Grainhouse = Forked dependencies (every critical component maintained)
- Documentation = Every design decision recorded (knowledge sovereignty)
- Eternal = 100-year perspective (frozen foundations, evolutionary layers)
Together → Sovereign, verifiable, performant, eternal systems.
Phased Implementation
Phase 1: Today (Use proven tools)
Applications: Clojure (on JVM/GraalVM)
Configuration: Nix (declarative system management)
Kernel: Linux (with seL4 research)
Hardware: x86/ARM (with RISC-V migration plan)
Strategy: Begin grainhouse (fork critical deps)
Phase 2: 2-5 years (Bridge technologies)
Applications: Clojure (GraalVM native image)
Configuration: Nix (refined grainhouse)
Research: Clojure semantics specified in Nock
Kernel: seL4 or verified microkernel
Hardware: RISC-V available, migrate gradually
Phase 3: 5-10 years (Verified stack)
Applications: Clojure (Nock-based compiler, verified)
Configuration: Nix (all deps in grainhouse)
Kernel: Nock-specified, formally verified
Hardware: RISC-V (open fabrication available?)
Achievement: Fully sovereign, auditable stack
Phase 4: 10+ years (Generational stability)
Applications: Mature Nock-Clojure ecosystem
Configuration: Stable Nix grainhouse (decades old)
Kernel: Proven microkernel (zero exploits)
Hardware: Multiple RISC-V vendors
Legacy: Systems last 100 years
We're not saying "rewrite everything in Nock tomorrow" (impractical).
We're saying:
- Use Clojure+Nix today (proven, productive)
- Specify critical systems in Nock (security-critical kernel, runtime)
- Optimize with GraalVM (performance today)
- Reimplement gradually (Nock-based compiler, verified over decades)
- Achieve sovereignty incrementally (grainhouse strategy)
Plant lens:
- Nock = genetic code (specification, eternal)
- Clojure/Nix = cultivated plants (productive, maintained)
- GraalVM = greenhouse (accelerated growth today)
- Nock-reimplementation = seed bank (genetic sovereignty, future-proof)
The 100-Year Perspective
Curtis Yarvin (Nock's creator) asked:
"If you were designing software to last 100 years, what would you do differently?"
Traditional answer: Pick stable languages (C), avoid trends.
Nock answer: Freeze the foundation (12 rules, eternal), evolve everything else on top.
Comparison:
Approach | Foundation | 100-Year Outlook |
---|---|---|
Linux | C + POSIX | Constant churn, security patches, breaking changes |
Nock | 12 frozen rules | Foundation never changes, apps evolve |
x86 | Growing ISA | Compatibility nightmare, legacy bloat |
RISC-V + Nock | Minimal, frozen | Clean slate, provable, eternal |
The valley chooses: Frozen foundations, evolutionary growth.
Try This
Exercise 1: Count Complexity
Compare specifications:
- Nock: 12 rules (2 pages)
- RISC-V RV32I: 47 instructions (clean!)
- WASM: 170+ instructions
- x86-64: 1,000+ instructions
- POSIX: 3,700 pages
Reflect: Which could you audit? Which could you verify?
Which would you trust for a 100-year system?
Exercise 2: Design a Nock-Specified System
Task: Sketch how you'd specify a simple OS in Nock.
Components:
- Process management (create, destroy, schedule)
- Memory management (allocate, free, map)
- IPC (send, receive, synchronize)
Approach: Each as a pure function (noun → noun).
Example:
[create-process
[executable-code [0 program-noun]]
[initial-memory [0 memory-size]]
→ [process-capability]]
Insight: Pure functions = easier to verify, easier to test.
Exercise 3: Explore GraalVM Clojure
Try GraalVM native image with Clojure:
# Install GraalVM
sdk install java 21.0.1-graal
# Create simple Clojure script
cat > hello.clj <<EOF
(ns hello)
(defn -main [& args]
(println "Hello from Clojure!"))
EOF
# Compile to native image
native-image --language:clojure -jar hello.jar hello
# Run (notice startup time!)
time ./hello
# Output: 10-50ms (vs 2-5 seconds on standard JVM)
Observe: GraalVM makes Clojure practical for system tools.
Question: Could we build this optimization layer on Nock semantics instead of JVM bytecode?
Exercise 4: Design Nock-Based Language Runtime
Task: Sketch how Clojure semantics could be specified in Nock.
Components:
- Persistent data structures (vectors, maps, sets)
- Function application (with closures)
- Lazy sequences (delayed evaluation)
- Concurrency primitives (atoms, refs, agents)
Approach: Each as pure Nock formula (noun → noun transformations).
Challenge: How do you represent time (for concurrency)?
Hint: Nock is deterministic → time must be explicit input (like game frame counter).
Going Deeper
Related Essays
- 9504: What Is Clojure? (Next!) - Practical Lisp (more usable than Nock)
- 9954: seL4 Verified Microkernel - Formal verification in practice
- 9960: The Grainhouse - Complete sovereignty architecture
- 9949: The Wise Elders - How systems compose
External Resources
- Nock Specification - Official 12 rules
- seL4 Whitepaper - Formally verified kernel
- RISC-V Specification - Open ISA
- Urbit - Production system running on Nock
Reflection Questions
- Is 12 rules too minimal? (Or is complexity the enemy of correctness?)
- Can you verify a system you can't hold in your head? (Linux = 30M lines)
- Should specification and implementation be separate? (Or is "code as spec" acceptable?)
- What would 100-year software look like? (Frozen foundation? Evolutionary layers?)
- Is formal verification worth the cost? (11 person-years for seL4—but zero exploits since 2009)
Summary
Nock is:
- 12 reduction rules (minimal VM)
- Combinator calculus (no variables, pure composition)
- Specification language (for OS design, language runtimes, verification)
- Eternal (frozen, never changes)
- Auditable (fits on 2 pages)
Key Insights:
- Minimalism enables verification (12 rules = tractable proofs)
- Frozen foundations enable longevity (100-year software)
- Specification ≠ implementation (Nock spec, optimized impl)
- Tree addressing eliminates variables (simpler semantics)
- Layered sovereignty (kernel + runtime both specified in Nock)
Complete Valley Stack:
Layer 1 - Foundation:
- RISC-V (open hardware)
- Nock (specification language)
- seL4-style microkernel (verified, Nock-specified)
Layer 2 - Runtime:
- Clojure (primary application language)
- Nix (system configuration language)
- GraalVM/Truffle (today's optimization)
- Nock-based compiler (future reimplementation)
Layer 3 - Strategy:
- Grainhouse (forked dependencies)
- Incremental sovereignty (phased over decades)
- Eternal perspective (100-year systems)
Implementation Path:
- Today: Clojure+Nix on JVM/GraalVM (productive)
- 5 years: Clojure semantics specified in Nock (research)
- 10 years: Nock-based Clojure compiler (verified, fast)
- Generations: Stable, sovereign, auditable stack
In Practice:
- Use Clojure for applications (proven, productive)
- Use Nix for infrastructure (reproducible, maintainable)
- Specify in Nock (kernel, critical runtimes)
- Optimize with GraalVM (performance today)
- Reimplement gradually (sovereignty over decades)
Plant lens:
- "Nock = genetic code (eternal specification)"
- "Clojure/Nix = cultivated crops (practical productivity)"
- "GraalVM = greenhouse (optimization today)"
- "Nock-reimplementation = seed sovereignty (future-proof)"
Next: We explore Clojure—a practical, modern Lisp that brings Nock's "code as data" philosophy to the JVM and JavaScript, with a thriving ecosystem and proven track record.
Navigation:
← Previous: 9502 (ode to nocturnal time) | Phase 1 Index | Next: 9504 (what is clojure)
Bridge to Sovereignty: For the complete vision, see:
- 9954 (seL4 Verified Kernel) - Formal verification
- 9960 (The Grainhouse) - Complete architecture
- 9949 (The Wise Elders) - System composition
Metadata:
- Phase: 1 (Foundations)
- Week: 1
- Prerequisites: 9500, 9501
- Concepts: Combinator calculus, minimal VMs, nouns, Nock rules, specification languages, formal verification, sovereignty
- Next Concepts: Clojure, homoiconicity, practical Lisp
- Wisdom Traditions: 💻 Modern computing (Nock) + 🔒 Formal verification (seL4) + 🌱 Sovereignty (valley vision)
Copyright © 2025 kae3g | Dual-licensed under Apache-2.0 / MIT
Competitive technology in service of clarity and beauty