725 lines
24 KiB
Markdown
725 lines
24 KiB
Markdown
# NexFS - Native Zig Flash Filesystem for NexusOS
|
||
|
||
> **The sovereign flash filesystem for Libertaria nodes and embedded devices**
|
||
|
||
[](https://opensource.org/licenses/LSL-1.0)
|
||
[](https://ziglang.org)
|
||
[](https://git.sovereign-society.org/nexus/nexfs)
|
||
|
||
---
|
||
|
||
## What is NexFS?
|
||
|
||
**NexFS** is a native Zig implementation of a flash-aware filesystem designed for **Libertaria nodes** and **embedded sovereign devices**. It provides reliable, wear-leveling-aware storage for resource-constrained environments where data integrity and flash longevity are critical.
|
||
|
||
### Key Design Goals
|
||
|
||
- **Flash-First Architecture**: Optimized for raw NAND/NOR flash with wear leveling awareness
|
||
- **Zero Dynamic Allocation**: All buffers provided by caller - no runtime memory allocation
|
||
- **Platform Agnostic**: Works with any flash HAL via callback interface
|
||
- **Data Integrity**: CRC32C checksums on all metadata structures
|
||
- **Sovereign by Design**: No external dependencies, no vendor lock-in, fully auditable
|
||
|
||
---
|
||
|
||
## Build Profiles & Architecture
|
||
|
||
**NexFS** implements a **modular Baukasten architecture** (SPEC-004) with three build profiles. Not one binary - three configurations compiled from modules:
|
||
|
||
### Three Build Profiles
|
||
|
||
| Profile | Modules | Footprint | Use Case |
|
||
|---------|---------|-----------|----------|
|
||
| **nexfs-core** | CAS + Block Valve + Hash | ~40KB | IoT, Satellite, Sensor |
|
||
| **nexfs-sovereign** | core + CDC + DAG | ~120KB | Phone, Laptop, Desktop |
|
||
| **nexfs-mesh** | sovereign + UTCP + Gossip | ~200KB | Home Box, Chapter Node |
|
||
|
||
### Module Compilation
|
||
|
||
NexFS uses Nim's compile-time conditionals for module selection:
|
||
|
||
```nim
|
||
# nexfs/config.nim
|
||
const
|
||
nexfs_cas* = defined(nexfs_cas) # CAS Layer (always)
|
||
nexfs_cdc* = defined(nexfs_cdc) # Content-Defined Chunking
|
||
nexfs_mesh* = defined(nexfs_mesh) # UTCP Cluster + Gossip
|
||
nexfs_dag* = defined(nexfs_dag) # Merkle DAG Directories
|
||
nexfs_dedup* = defined(nexfs_dedup) # Cross-Node Dedup
|
||
```
|
||
|
||
**Build Commands:**
|
||
```bash
|
||
# Core profile (IoT sensor)
|
||
nim c -d:nexfs_cas nexfs
|
||
|
||
# Sovereign profile (laptop)
|
||
nim c -d:nexfs_cas -d:nexfs_cdc -d:nexfs_dag nexfs
|
||
|
||
# Mesh profile (home box)
|
||
nim c -d:nexfs_cas -d:nexfs_cdc -d:nexfs_dag -d:nexfs_mesh nexfs
|
||
```
|
||
|
||
### Profile Comparison
|
||
|
||
**nexfs-core** is your LittleFS successor:
|
||
- ✅ Robust, power-safe
|
||
- ✅ Content-addressed storage
|
||
- ✅ Block-level wear leveling
|
||
- ❌ No network code
|
||
- ❌ No chunker
|
||
- ❌ No gossip
|
||
- **Target:** Root partition for everything that blinks and beeps
|
||
|
||
**nexfs-sovereign** adds local intelligence:
|
||
- ✅ CDC-Chunking for efficient snapshots
|
||
- ✅ Local deduplication
|
||
- ✅ Merkle DAGs for Time-Travel
|
||
- ❌ Still single-node
|
||
- **Target:** Phone, laptop, desktop
|
||
|
||
**nexfs-mesh** enables network layer:
|
||
- ✅ UTCP cluster communication
|
||
- ✅ Gossip-based peer discovery
|
||
- ✅ Cross-node deduplication
|
||
- ✅ Chapter-Mesh integration
|
||
- ✅ Kinetic Credits economy
|
||
- **Target:** Home box, Chapter node
|
||
|
||
---
|
||
|
||
## Specifications
|
||
|
||
NexFS is defined by three SPECs that build on each other:
|
||
|
||
| SPEC | Name | Scope | Size |
|
||
|------|------|-------|------|
|
||
| **SPEC-084** | NexFS Core Format | Superblock, Block Pointers, Hash-ID, Profile-Byte | Foundation |
|
||
| **SPEC-085** | NexFS Sovereign Extensions | CDC Chunking, Merkle DAG, Local Dedup, Time Travel | +80KB |
|
||
| **SPEC-704** | UTCP Storage Extensions | UTCP Storage Ops, Gossip, Chapter-Mesh, Kinetic Credits | +80KB |
|
||
|
||
**Dependency Chain:**
|
||
```
|
||
SPEC-084 (Core) → SPEC-085 (Sovereign) → SPEC-704 (Mesh)
|
||
↓ ↓ ↓
|
||
40KB +80KB +80KB
|
||
IoT Laptop Home Box
|
||
```
|
||
|
||
Each SPEC is **independently implementable**. `core` compiles without the others. `sovereign` needs `core`. `mesh` needs both.
|
||
|
||
---
|
||
|
||
## Use Cases
|
||
|
||
### 1. Libertaria Mesh Nodes
|
||
|
||
**Primary Use Case**: Storage layer for Libertaria Capsule nodes
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ Libertaria Capsule Node │
|
||
│ │
|
||
│ ┌─────────────────────────────────┐ │
|
||
│ │ L3 Gossip (QVL Trust Edges) │ │
|
||
│ └─────────────────────────────────┘ │
|
||
│ ┌─────────────────────────────────┐ │
|
||
│ │ L2 Session (Noise Handshakes) │ │
|
||
│ └─────────────────────────────────┘ │
|
||
│ ┌─────────────────────────────────┐ │
|
||
│ │ L1 Identity (SoulKeys) │ │
|
||
│ └─────────────────────────────────┘ │
|
||
│ ┌─────────────────────────────────┐ │
|
||
│ │ NexFS (Persistent Storage) │◄──┘
|
||
│ └─────────────────────────────────┘
|
||
│ ┌─────────────────────────────────┐
|
||
│ │ Raw Flash (NAND/NOR/SPI) │
|
||
│ └─────────────────────────────────┘
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
**Why NexFS for Libertaria?**
|
||
- **Persistence**: SoulKeys, peer tables, trust graphs survive reboots
|
||
- **Integrity**: CRC32C ensures metadata hasn't been corrupted
|
||
- **Wear Leveling**: Tracks erase counts to maximize flash lifespan
|
||
- **Minimal Footprint**: Zero allocation design fits embedded constraints
|
||
- **Fast Boot**: No journal replay, direct mount from superblock
|
||
|
||
### 2. Embedded Sovereign Devices
|
||
|
||
**Secondary Use Case**: IoT devices, Raspberry Pi, ESP32, microcontrollers
|
||
|
||
**Examples:**
|
||
- **Solar Monitor Nodes**: Store sensor readings, config, firmware updates
|
||
- **Weather Network**: Log environmental data locally before sync
|
||
- **Pager Devices**: Message queue persistence
|
||
- **Home Automation**: Device state, automation rules, logs
|
||
|
||
**Why NexFS for Embedded?**
|
||
- **Raw Flash Support**: Works directly with SPI flash, no FTL layer needed
|
||
- **Power-Loss Resilience**: Dual superblock backup survives sudden power loss
|
||
- **Deterministic**: Fixed buffer sizes, predictable memory usage
|
||
- **No OS Dependencies**: Works bare-metal or with any RTOS
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
### On-Disk Layout
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ Block 0: Primary Superblock (128 bytes) │
|
||
├─────────────────────────────────────────────┤
|
||
│ Block 1: Backup Superblock (128 bytes) │
|
||
├─────────────────────────────────────────────┤
|
||
│ Blocks 2-N: Block Allocation Map (BAM) │
|
||
│ - Tracks allocation status │
|
||
│ - Records erase counts (wear leveling) │
|
||
│ - Bad block marking │
|
||
├─────────────────────────────────────────────┤
|
||
│ Blocks N+1-N+4: Inode Table │
|
||
│ - File/directory metadata │
|
||
│ - Inode IDs 1-128 │
|
||
├─────────────────────────────────────────────┤
|
||
│ Blocks N+5+: Data Blocks │
|
||
│ - File/directory contents │
|
||
│ - Wear-leveled allocation │
|
||
└─────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Key Components
|
||
|
||
**1. Superblock**
|
||
- Magic number: `0x4E455846` ("NEXF")
|
||
- Generation counter for crash recovery
|
||
- Mount count for health monitoring
|
||
- CRC32C checksum for integrity
|
||
|
||
**2. Block Allocation Map (BAM)**
|
||
- Per-block metadata: allocated, bad, reserved, needs_erase
|
||
- Erase count tracking for wear leveling
|
||
- Generation counter for block age
|
||
|
||
**3. Inode Table**
|
||
- File/directory metadata
|
||
- Supports: Regular, Directory, Symlink, Device nodes
|
||
- Max filename: 255 characters
|
||
|
||
**4. Flash Interface**
|
||
```zig
|
||
pub const FlashInterface = struct {
|
||
read: *const fn (ctx: *anyopaque, addr: u64, buffer: []u8) NexFSError!usize,
|
||
write: *const fn (ctx: *anyopaque, addr: u64, buffer: []const u8) NexFSError!void,
|
||
erase: *const fn (ctx: *anyopaque, block_addr: BlockAddr) NexFSError!void,
|
||
sync: *const fn (ctx: *anyopaque) NexFSError!void,
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## Features
|
||
|
||
### ✅ Implemented (v0.1.0)
|
||
|
||
- **Format/Initialization**: `format()` creates fresh filesystem
|
||
- **Superblock Management**: Primary + backup with checksums
|
||
- **Block Allocation**: BAM-based allocation with wear tracking
|
||
- **Inode Operations**: Create, read, write, delete
|
||
- **Directory Operations**: mkdir, rmdir, readdir, lookup
|
||
- **File Operations**: open, read, write, close, seek
|
||
- **Path Resolution**: Full path support (`/path/to/file`)
|
||
- **Checksum Verification**: CRC32C on all metadata
|
||
- **Zero Allocation**: All buffers provided by caller
|
||
|
||
### 🚧 Planned (Future Versions)
|
||
|
||
- **Wear Leveling Algorithm**: Active block rotation based on erase counts
|
||
- **Bad Block Management**: Automatic bad block detection and marking
|
||
- **Defragmentation**: Reclaim fragmented data blocks
|
||
- **Snapshots**: Point-in-time filesystem snapshots
|
||
- **Compression**: Optional LZ4 compression for data blocks
|
||
- **Encryption**: Optional XChaCha20-Poly1305 encryption
|
||
|
||
---
|
||
|
||
## Chapter-Mesh Architecture (nexfs-mesh)
|
||
|
||
### The Strategic Moat
|
||
|
||
When a user installs a Sovereign device, NexFS creates a two-partition layout:
|
||
|
||
```
|
||
┌─ /dev/nvme0 ─────────────────────────────────┐
|
||
│ │
|
||
│ Partition 1: nexfs-sovereign (Root, Private)│
|
||
│ ├── /Cas (System, Immutable) │
|
||
│ ├── /Nexus (Config, Encrypted) │
|
||
│ └── /Data (User, Encrypted) │
|
||
│ │
|
||
│ Partition 2: nexfs-mesh (Chapter Pool) │
|
||
│ ├── Encrypted at rest (Monolith) │
|
||
│ ├── Auto-joins Chapter via UTCP Discovery │
|
||
│ ├── Contributes: Storage + Bandwidth │
|
||
│ └── Receives: Redundancy + Content Access │
|
||
│ │
|
||
└────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Installation Flow
|
||
|
||
```bash
|
||
# During Sovereign installation
|
||
nexus forge --chapter "frankfurt-01"
|
||
|
||
# User prompt:
|
||
# "How much storage do you want to contribute to the Chapter Network?"
|
||
# [Slider: 10GB ... 500GB ... 2TB]
|
||
# Default: 10% of disk or 50GB, whichever is smaller
|
||
|
||
nexfs format /dev/nvme0p2 --mode sovereign-mesh \
|
||
--chapter-id "frankfurt-01" \
|
||
--quota 50G \
|
||
--replication-factor 3
|
||
```
|
||
|
||
### What Happens in the Background
|
||
|
||
1. **UTCP Discovery** (SPEC-703 Pattern):
|
||
- Box broadcasts `PEER_ANNOUNCE` on local network
|
||
- Connects to known Chapter gateways
|
||
|
||
2. **Gossip Sync**:
|
||
- Learns which other Sovereigns are online
|
||
- Exchanges peer lists and chunk availability
|
||
|
||
3. **Lazy Replication**:
|
||
- Popular chunks (Nip packages, community content) automatically cached
|
||
- Replication factor enforced (default: 3 copies)
|
||
|
||
4. **Sealed Storage**:
|
||
- User cannot see Chapter partition as normal directory
|
||
- It's an opaque block pool
|
||
- No user snooping on transit data possible
|
||
|
||
### The Economy (Kinetic Credits)
|
||
|
||
Integration with **Kinetic Economy Model** (SPEC-053):
|
||
|
||
```
|
||
You give: 100GB Mesh-Storage + Uptime
|
||
You get: Kinetic Credits
|
||
You use: Credits for Package-Downloads, Mesh-Access, Priority-Routing
|
||
```
|
||
|
||
**Engineered Reciprocity** - No altruism, no charity:
|
||
- More contribution = more credits
|
||
- No contribution = still can read (Commonwealth packages are free)
|
||
- Premium content and priority bandwidth cost credits
|
||
|
||
### The Torrent Killer
|
||
|
||
**Why NexFS Chapter-Mesh beats BitTorrent:**
|
||
|
||
| Feature | BitTorrent | NexFS Chapter-Mesh |
|
||
|---------|------------|-------------------|
|
||
| **FS Integration** | Separate client | Native FS (`nip install firefox`) |
|
||
| **Deduplication** | Full file transfer | CAS-Dedup (5% delta transfer) |
|
||
| **Encryption** | Optional | Encrypted at rest by default |
|
||
| **NAT Traversal** | Problematic | UTCP CellID routing (no NAT issues) |
|
||
| **Discovery** | Tracker/DHT | Gossip-based peer discovery |
|
||
| **Economy** | None | Kinetic Credits |
|
||
|
||
**Example:** Firefox 120.0.1 and 120.0.2 share 95% of chunks:
|
||
- BitTorrent: Transfer entire `.tar.gz` again
|
||
- NexFS: Transfer only 5% difference
|
||
|
||
### Superblock Extension
|
||
|
||
One byte in the superblock determines the profile:
|
||
|
||
```nim
|
||
type NexfsSuperblock* = object
|
||
magic*: uint32 # "NXFS"
|
||
version*: uint16
|
||
hash_algo*: uint8 # 0x00=BLAKE3-256, 0x01=BLAKE3-128, 0x02=XXH3-128
|
||
profile*: uint8 # 0x00=core, 0x01=sovereign, 0x02=mesh ← NEW
|
||
chapter_id*: CellID # 128-bit (only for mesh, otherwise 0)
|
||
mesh_quota*: uint64 # Bytes dedicated to mesh (only for mesh)
|
||
replication_target*: uint8 # Desired copies (default 3)
|
||
# ... rest as usual
|
||
```
|
||
|
||
### Filesystem Hierarchy Extension
|
||
|
||
```
|
||
/Data/
|
||
├── Volume/
|
||
│ ├── Local/ # Standard
|
||
│ ├── Remote/ # Cloud-Mounts
|
||
│ ├── External/ # USB
|
||
│ └── Mesh/ # NEW: Chapter Pool
|
||
│ ├── .quota # 50GB
|
||
│ ├── .chapter-id # frankfurt-01
|
||
│ └── .peers # Known CellIDs
|
||
```
|
||
|
||
### UTCP Storage Protocol (SPEC-704)
|
||
|
||
**Wire Protocol Extensions:**
|
||
|
||
| Category | Operations | Size |
|
||
|----------|-----------|------|
|
||
| **Block Ops** | GET, PUT, DELETE, REPLICATE, VERIFY, REPAIR, STATS | 7 ops |
|
||
| **DAG Ops** | RESOLVE, ANCESTORS, DIFF | 3 ops |
|
||
| **Peer Ops** | ANNOUNCE, LEAVE, HEARTBEAT | 3 ops |
|
||
|
||
All operations use **16-byte extension header** on existing UTCP frames.
|
||
|
||
**Key Features:**
|
||
- Gossip-based peer discovery
|
||
- Credit-based flow control (SPEC-702 pattern reuse)
|
||
- Replication-factor enforcement
|
||
- Chapter-Mesh integration with Kinetic Credits
|
||
|
||
---
|
||
|
||
## Quick Start
|
||
|
||
### Installation
|
||
|
||
Add NexFS to your `build.zig.zon`:
|
||
|
||
```zig
|
||
.{
|
||
.name = "your-project",
|
||
.version = "0.1.0",
|
||
.dependencies = .{
|
||
.nexfs = .{
|
||
.url = "https://git.sovereign-society.org/nexus/nexfs/archive/main.tar.gz",
|
||
.hash = "...",
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
### Example: Basic Usage
|
||
|
||
```zig
|
||
const std = @import("std");
|
||
const nexfs = @import("nexfs");
|
||
|
||
// 1. Define your flash interface
|
||
const MyFlash = struct {
|
||
flash_data: []u8,
|
||
|
||
pub fn read(ctx: *anyopaque, addr: u64, buffer: []u8) nexfs.NexFSError!usize {
|
||
const self = @ptrCast(*MyFlash, @alignCast(ctx));
|
||
@memcpy(buffer, self.flash_data[addr..][0..buffer.len]);
|
||
return buffer.len;
|
||
}
|
||
|
||
pub fn write(ctx: *anyopaque, addr: u64, buffer: []const u8) nexfs.NexFSError!void {
|
||
const self = @ptrCast(*MyFlash, @alignCast(ctx));
|
||
@memcpy(self.flash_data[addr..][0..buffer.len], buffer);
|
||
}
|
||
|
||
pub fn erase(ctx: *anyopaque, block_addr: nexfs.BlockAddr) nexfs.NexFSError!void {
|
||
// Erase flash block (set to 0xFF for NAND)
|
||
}
|
||
|
||
pub fn sync(ctx: *anyopaque) nexfs.NexFSError!void {
|
||
// Flush any caches
|
||
}
|
||
};
|
||
|
||
pub fn main() !void {
|
||
var flash = MyFlash{ .flash_data = try allocator.alloc(u8, 1024 * 1024) };
|
||
|
||
// 2. Configure NexFS
|
||
var read_buf: [4096]u8 = undefined;
|
||
var write_buf: [4096]u8 = undefined;
|
||
var workspace: [256]u8 = undefined;
|
||
|
||
const config = nexfs.Config{
|
||
.flash = .{
|
||
.ctx = &flash,
|
||
.read = MyFlash.read,
|
||
.write = MyFlash.write,
|
||
.erase = MyFlash.erase,
|
||
.sync = MyFlash.sync,
|
||
},
|
||
.device_size = 1024 * 1024,
|
||
.block_size = 4096,
|
||
.block_count = 256,
|
||
.page_size = 256,
|
||
.checksum_algo = .CRC32C,
|
||
.read_buffer = &read_buf,
|
||
.write_buffer = &write_buf,
|
||
.workspace = &workspace,
|
||
.time_source = null,
|
||
.verbose = true,
|
||
};
|
||
|
||
// 3. Format the filesystem
|
||
try nexfs.format(&config.flash, &config, &write_buf);
|
||
|
||
// 4. Create a file
|
||
var fs = try nexfs.NexFS.init(allocator, config);
|
||
const fd = try fs.create("/config.txt");
|
||
try fs.write(fd, "hello nexfs");
|
||
try fs.close(fd);
|
||
|
||
// 5. Read it back
|
||
var buf: [64]u8 = undefined;
|
||
const fd2 = try fs.open("/config.txt");
|
||
const len = try fs.read(fd2, &buf);
|
||
try std.io.getStdOut().writeAll(buf[0..len]);
|
||
try fs.close(fd2);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Configuration Options
|
||
|
||
```zig
|
||
const Config = struct {
|
||
flash: FlashInterface, // Your flash HAL
|
||
device_size: u64, // Total flash size in bytes
|
||
block_size: BlockSize, // Flash block size (512, 1024, 2048, 4096)
|
||
block_count: u32, // Number of blocks
|
||
page_size: PageSize, // Flash page size for alignment
|
||
checksum_algo: ChecksumAlgo, // None, CRC16, or CRC32C
|
||
read_buffer: []u8, // Buffer >= block_size
|
||
write_buffer: []u8, // Buffer >= block_size
|
||
workspace: []u8, // Buffer >= page_size
|
||
time_source: ?TimeSource, // Optional timestamp provider
|
||
verbose: bool, // Enable debug logging
|
||
};
|
||
```
|
||
|
||
### Recommended Configurations
|
||
|
||
**1. Raspberry Pi with SPI Flash (1MB)**
|
||
```zig
|
||
.block_size = 4096,
|
||
.page_size = 256,
|
||
.block_count = 256,
|
||
.checksum_algo = .CRC32C,
|
||
```
|
||
|
||
**2. ESP32 with Flash (4MB)**
|
||
```zig
|
||
.block_size = 4096,
|
||
.page_size = 256,
|
||
.block_count = 1024,
|
||
.checksum_algo = .CRC32C,
|
||
```
|
||
|
||
**3. Microcontroller with NOR Flash (512KB)**
|
||
```zig
|
||
.block_size = 2048,
|
||
.page_size = 256,
|
||
.block_count = 256,
|
||
.checksum_algo = .CRC16, // Faster on limited CPUs
|
||
```
|
||
|
||
---
|
||
|
||
## Design Philosophy
|
||
|
||
### Sovereign Storage Principles
|
||
|
||
1. **No Secrets**: All code is open source and auditable (LSL-1.0)
|
||
2. **No Dependencies**: Zero external libraries, pure Zig
|
||
3. **No Vendor Lock-in**: Standard interfaces, portable anywhere
|
||
4. **No Hidden Allocation**: Explicit memory management
|
||
5. **No Trust Required**: Verify integrity with checksums
|
||
|
||
### Flash-Aware Design
|
||
|
||
**Why Raw Flash?**
|
||
- **Predictable Performance**: No FTL latency spikes
|
||
- **Full Control**: Wear leveling algorithm you control
|
||
- **Longer Lifespan**: Avoid consumer-grade FTL write amplification
|
||
- **Lower Power**: No background garbage collection
|
||
|
||
**Wear Leveling Strategy:**
|
||
- Track erase counts per block (BAM)
|
||
- Prefer blocks with lowest erase counts for writes
|
||
- Reserve high-erase-count blocks for cold data
|
||
- Target: Even wear distribution across flash lifetime
|
||
|
||
---
|
||
|
||
## Performance Characteristics
|
||
|
||
| Operation | Typical Latency | Notes |
|
||
|-----------|----------------|-------|
|
||
| Mount | < 10ms | Read superblock, validate checksum |
|
||
| Format | 100-500ms | Initialize all metadata blocks |
|
||
| File Create | 5-20ms | Allocate inode, write metadata |
|
||
| File Read (4KB) | 1-5ms | Single block read |
|
||
| File Write (4KB) | 10-30ms | Erase + write cycle |
|
||
| Directory Lookup | 1-5ms | Inode table scan |
|
||
|
||
**Memory Requirements:**
|
||
- **Minimum**: 2 × block_size + page_size (e.g., 8KB + 256B = ~8.5KB)
|
||
- **Recommended**: 2 × block_size + 2 × page_size (for async ops)
|
||
- **Allocator**: Not required (zero dynamic allocation)
|
||
|
||
---
|
||
|
||
## Roadmap
|
||
|
||
### Version 0.2.0 (Q2 2026) - Sovereign Profile
|
||
**Focus:** SPEC-085 Implementation
|
||
- [ ] FastCDC chunker implementation
|
||
- [ ] CAS store with inline dedup
|
||
- [ ] Merkle DAG directory structure
|
||
- [ ] TimeWarp snapshots (`nexfs snap create/rollback/diff`)
|
||
- [ ] Build profiles: core vs sovereign
|
||
- [ ] Active wear leveling algorithm
|
||
- [ ] Bad block management
|
||
|
||
### Version 0.3.0 (Q3 2026) - Mesh Profile
|
||
**Focus:** SPEC-704 Implementation
|
||
- [ ] UTCP storage protocol (7 Block Ops, 3 DAG Ops, 3 Peer Ops)
|
||
- [ ] Gossip-based peer discovery
|
||
- [ ] Cross-node deduplication
|
||
- [ ] Chapter-Mesh integration
|
||
- [ ] Kinetic Credits integration
|
||
- [ ] Credit-based flow control
|
||
- [ ] Compression support (LZ4)
|
||
- [ ] Defragmentation tool
|
||
- [ ] Filesystem check utility (fsck)
|
||
|
||
### Version 1.0.0 (Q4 2026) - Production Hardening
|
||
**Focus:** Production Readiness
|
||
- [ ] Encryption support (XChaCha20-Poly1305)
|
||
- [ ] CRDT for concurrent DAG edits
|
||
- [ ] Multi-Chapter federation
|
||
- [ ] Performance benchmarks
|
||
- [ ] Production-hardened
|
||
- [ ] Full Libertaria stack integration
|
||
|
||
### Future Considerations
|
||
- **CRDT-Specification** for concurrent DAG edits (Phase 50+)
|
||
- **Multi-Chapter-Federation** for cross-chapter chunk exchange (Phase 50+)
|
||
|
||
**Note:** Features grow into existing SPECs as Sections when needed, not as standalone documents.
|
||
|
||
---
|
||
|
||
## Testing
|
||
|
||
**Current Test Coverage:** 251/253 tests passing (99.2%)
|
||
|
||
```bash
|
||
# Run tests
|
||
zig build test
|
||
|
||
# Run with verbose output
|
||
zig build test -Dverbose
|
||
```
|
||
|
||
**Test Categories:**
|
||
- ✅ Superblock validation
|
||
- ✅ Checksum verification
|
||
- ✅ Block allocation/deallocation
|
||
- ✅ Inode operations
|
||
- ✅ Directory operations
|
||
- ✅ File operations
|
||
- ✅ Path resolution
|
||
- 🔄 Wear leveling (in progress)
|
||
- 🔄 Bad block handling (planned)
|
||
|
||
---
|
||
|
||
## Security Considerations
|
||
|
||
**Data Integrity:**
|
||
- CRC32C protects all metadata from silent corruption
|
||
- Dual superblock survives single-block corruption
|
||
- Bad block marking prevents data loss
|
||
|
||
**Power-Loss Resilience:**
|
||
- Primary + backup superblock
|
||
- Metadata writes are atomic (single block)
|
||
- No journal to replay
|
||
|
||
**Future Security Features:**
|
||
- Optional encryption at rest (v1.0)
|
||
- Authenticated encryption (AEAD)
|
||
- Key derivation from SoulKey (Libertaria integration)
|
||
|
||
---
|
||
|
||
## Contributing
|
||
|
||
**Development Status:** Alpha (v0.1.0)
|
||
|
||
**Contribution Areas:**
|
||
- Wear leveling algorithm improvements
|
||
- Bad block detection strategies
|
||
- Performance optimizations
|
||
- Test coverage improvements
|
||
- Documentation enhancements
|
||
|
||
**Code Style:**
|
||
- Follow Zig style guidelines
|
||
- SPDX license headers required
|
||
- BDD-style tests preferred
|
||
- Panopticum architecture compliance
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
**License:** LSL-1.0 (Libertaria Source License 1.0)
|
||
|
||
**Summary:**
|
||
- ✅ Open source and auditable
|
||
- ✅ Free to use for sovereign applications
|
||
- ✅ Modifications must be contributed back
|
||
- ✅ No commercial restrictions for sovereign use cases
|
||
|
||
See [LICENSE](LICENSE) for full text.
|
||
|
||
---
|
||
|
||
## Community
|
||
|
||
**Repository:** https://git.sovereign-society.org/nexus/nexfs
|
||
|
||
**Organization:** [Nexus](https://git.sovereign-society.org/nexus)
|
||
- rumpk - Runtime package manager
|
||
- nip - Nexus package format
|
||
- nexus - Core utilities
|
||
- nipbox - Package repository
|
||
- **nexfs** - Flash filesystem
|
||
|
||
**Related Projects:**
|
||
- [Libertaria Stack](https://git.sovereign-society.org/libertaria/libertaria-stack) - P2P mesh networking
|
||
- [Janus Language](https://git.sovereign-society.org/janus/janus) - Systems programming language
|
||
|
||
---
|
||
|
||
## Acknowledgments
|
||
|
||
**Inspired By:**
|
||
- **LittleFS** - Flash-friendly embedded filesystem
|
||
- **JFFS2** - Journaling flash filesystem
|
||
- **YAFFS2** - Yet another flash filesystem
|
||
|
||
**Built With:**
|
||
- **Zig** - Systems programming language
|
||
- **Libertaria** - Sovereign P2P mesh network
|
||
|
||
---
|
||
|
||
**NexFS** - *Storage for Sovereign Systems*
|
||
|
||
*Part of the Nexus ecosystem for Libertaria nodes and embedded devices*
|