Design Philosophy
Nash achieves complete sandboxing through structural enforcement, not just policy:std::process::Commandis never imported anywhere in the codebase- All file I/O goes through the VFS API — host paths are unreachable without
--bind - Read-only mounts reject writes at the VFS layer, not the command layer
- Subshells run on a cloned context — environment mutations don’t escape
( )
The zero-system-calls guarantee is enforced at compile time by simply not importing the necessary modules to spawn processes.
Module Organization
Nash’s source code is organized into five main modules, each with a clear responsibility:Separation of Concerns
The parser and runtime are completely decoupled:Parser (src/parser/)
Parser (src/parser/)
The parser module converts raw shell input strings into an Abstract Syntax Tree (AST). It knows nothing about execution semantics.Key files:
lexer.rs— Tokenizes input into symbols likePipe,And,Word, etc.ast.rs— DefinesExpr,Word,WordPart, andRedirectModetypesmod.rs— Recursive-descent parser that builds the AST
- Tokenization (handling quotes, escapes, operators)
- AST construction (commands, pipes, redirects, chains)
- Syntax validation
Runtime (src/runtime/)
Runtime (src/runtime/)
The runtime module evaluates AST expressions and manages execution context. It knows nothing about syntax.Key files:
executor.rs— AST walker with zero system calls (src/runtime/executor.rs:1-716)context.rs— Mutable session state (cwd, env, VFS, history)output.rs— Command output structure
- AST traversal and evaluation
- Word expansion (variables, command substitution)
- Context management (working directory, environment)
- Builtin dispatch
VFS (src/vfs/)
VFS (src/vfs/)
The Virtual Filesystem provides an in-memory Unix-like filesystem with optional host mounts.Key files:
mod.rs— Core VFS operations (read, write, mkdir, rm, list)node.rs—FsNodeenum (File | Directory)path.rs— Path manipulation (normalize, join, parent, basename)mount.rs— Host directory binding support
- In-memory file storage
- Directory tree operations
- Host mount overlay
- Read-only mount enforcement
Builtins (src/builtins/)
Builtins (src/builtins/)
Built-in commands that provide shell functionality without invoking external processes.Structure:
mod.rs—Builtintrait and dispatch table (src/builtins/mod.rs:38-82)- One
.rsfile per command (28 total)
- Implement all shell commands
- Parse command-line arguments
- Operate on Context and VFS
- Return Output structure
Component Interaction
Here’s how data flows through Nash when executing a command:ASCII Architecture Diagram
From the Nash README (README.md:348-371):Key Design Decisions
1. Parser-Runtime Decoupling
The parser produces anExpr tree and knows nothing about execution. The runtime walks the tree and knows nothing about syntax. This enables:
- Independent testing of each layer
- Easy addition of new syntax forms
- Clear separation of concerns
2. VFS-First Design
All file operations go through the VFS API. Builtins never touchstd::fs directly:
3. Trait-Based Builtin System
Every builtin implements the same trait (src/builtins/mod.rs:38-41):4. Context as Shared State
TheContext structure (src/runtime/context.rs:7-16) holds all mutable session state:
&mut Context, allowing them to modify environment, change directories, or write files.
