Lode Coded Project vs Raw Code
@fjzeit - May 1st, 2026 - 15 min read
Here I compare two reports run against the same repo.
The project, SP/M, is a hardware bring-up OS for ESP32 microcontrollers. It provides an interactive shell for GPIO/I2C/SPI/ADC experimentation, a script interpreter for automated diagnostics and prototyping, and a built-in ed editor. The goal is fast iteration during hardware development. Allowing developers to test their board, and their software without compile/flash cycles.
Setup
The reports were generated using my own micro-IDE which is specifically designed to support the lode coding method and other conversational AI assisted development.
In Report A the model had exposure to the entire project, including its lode.
In Report B the lode was removed, leaving only the code. I also had to remove the .git folder as on first run the model decided to extract the lode files from git history… surprisingly.
Each report was generated from a fresh empty session.
Comparison Overview
This comparison reveals something important about knowledge representation for code understanding, and Lode Coding in particular.
The lode-enabled model had structured knowledge built as a byproduct of lode coding the SP/M system. This knowledge shaped how the model understood the system and responded to the question “explain the OS aspects of this implementation”.
The lode provided additional project history and context that source code alone cannot. Specifically:
-
Conceptual framing: The CP/M heritage and design philosophy came through clearly in Report A. Source code shows how things work, but the lode captures why they were designed that way.
-
Architecture-first thinking: Report A’s clean layering diagram and “what’s NOT there” section shows how the lode captured high-level design decisions. Reading code bottom-up makes it harder to extract these architectural choices.
-
Domain context: Terms like “TPA”, “jump table”, “Harvard architecture implications” were used with more precision in Report A with the lode providing the conceptual vocabulary that made these explanations clearer.
-
Pedagogical structure: Report A’s flow (architecture → process → memory → filesystem → loading) shows the lode captured a narrative and mental model, not just facts.
Report B is mostly correct and demonstrates the model successfully reverse-engineered the OS from source. Although it does infer some behaviours from the technology used, and hallucinates the meaning of the name SP/M.
Report A reads like it was written by someone who designed the system, while Report B reads like it was written by someone who studied it. The lode captures design intent and conceptual models that are not visible from the code alone.
This is a compelling argument for structured knowledge representation and Lode Coding by providing the conceptual scaffolding necessary for sustained development and quality model interaction.
I have provided both reports below in case you’re interested.
Stats
Model: Kimi-K2.6 (Ollama Cloud, 256K context)
| Report | Time | Turns | Tool Calls |
|---|---|---|---|
| A | 46s | 8 | 19 |
| B | 1m 27s | 9 | 24 |
Report A - generated from the full project, include its Lode
Prompt: explain the OS aspects of this implementation
[intermediate turns redacted for brevity]
The user wants me to explain the OS aspects of this implementation. I now have a comprehensive understanding from the lode files and source code. Let me synthesize this into a clear, structured explanation covering the key OS aspects:
- System Architecture & Layering - How SP/M is structured as an OS
- Process Model - What runs and how (CCP shell, transient programs, scripts)
- Memory Management - TPA, IRAM/DRAM split, Harvard architecture handling
- File System - VFS, mount points, aliases
- Program Loading & Execution - .SPM format, relocations, jump table (syscall interface)
- Concurrency - Dual-core model (Core 0 vs Core 1)
- Device/Hardware Interface - HAL, shell commands
- What’s NOT there - No MMU, no preemptive multitasking, no networking
Let me provide a comprehensive but concise explanation.
SP/M is a minimal operating system for ESP32 microcontrollers, built on top of FreeRTOS/ESP-IDF but presenting its own distinct OS personality. Here are the key OS aspects:
1. System Architecture & Layering
SP/M follows a layered design with clear separation between kernel services and user code:
┌────────────────────────────────────────────┐
│ User Space: Scripts (.sps) │
│ Transient Programs (.spm) │
├────────────────────────────────────────────┤
│ Kernel: CCP │ VFS │ Loader │ Script │
│ Shell │ │ │ Interpreter│
├────────────────────────────────────────────┤
│ HAL (GPIO, UART, I2C, SPI, ADC) │
├────────────────────────────────────────────┤
│ ESP-IDF (FreeRTOS, drivers) │
└────────────────────────────────────────────┘
The kernel is monolithic — all services (shell, filesystem, loader, interpreter) compile into a single binary (~440KB).
2. Process Model
SP/M has no processes in the traditional sense. Instead, it has three execution contexts:
| Context | Type | Lifetime | Core |
|---|---|---|---|
| CCP Shell | Infinite loop | Forever | Core 0 |
| Transient Programs | Loaded binary | Until exit | Core 1 (dual-core) |
| Scripts | Interpreted text | Until completion | Core 0 |
There is no preemptive multitasking. Only one transient program or script runs at a time. The shell blocks during script execution and remains responsive during transient program execution (because programs run on Core 1).
3. Memory Management
SP/M runs on ESP32’s Harvard architecture, which has separate executable (IRAM) and data (DRAM) memory regions. The OS handles this explicitly:
- TPA (Transient Program Area): Dynamically allocated region for loading user programs
- IRAM region: 32KB for
.text(code), allocated withMALLOC_CAP_EXEC - DRAM region: 16KB for
.rodata,.data,.bss, allocated withMALLOC_CAP_8BIT - Stack: 8KB provided by FreeRTOS
- IRAM region: 32KB for
The loader performs IRAM-safe memory operations because IRAM requires 32-bit aligned access — byte-level memcpy/memset will crash. The loader uses word-aligned copies.
There is no virtual memory, no memory protection, and no address space isolation. Everything shares the same physical address space.
4. File System & VFS
SP/M implements a Virtual File System layer on top of ESP-IDF’s VFS:
| Mount Point | Backend | Purpose |
|---|---|---|
/void/ |
Virtual | Always exists, always empty (graceful degradation) |
/nv0/ |
Internal flash (LittleFS) | Persistent config/scratch |
/sd0/ |
SD card (FAT32) | Removable storage |
Path aliases provide named shortcuts:
sys:→/sd0/system/→/nv0/system/→/void/(cascading fallback)null:→/void/
The VFS root / is a virtual namespace — it lists mount points but cannot be opened with opendir().
5. Program Loading & Execution Model
SP/M’s most distinctive OS feature is its transient program system — a deliberate homage to CP/M’s COM files:
The .SPM Format
A custom binary format (28-byte header + sections + relocation table):
[header: magic, version, entry, sizes]
[.text section]
[.rodata section]
[.data section]
[relocation table]
Loading Process
- Read header, validate magic (
SPM\x01) and version - Allocate IRAM (for code) and DRAM (for data) separately
- Copy sections into respective regions
- Apply relocations — translate addresses from the original contiguous ELF layout to the split IRAM/DRAM runtime layout
- Launch program
The Jump Table (System Call Interface)
Transient programs cannot call ESP-IDF directly. Instead, the kernel passes a function pointer table (spm_table_t) at program entry:
typedef struct spm_table {
// Console I/O
int (*putchar_fn)(int c);
int (*getchar_fn)(void);
// File I/O (POSIX-like)
int (*open_fn)(const char *path, int flags);
int (*read_fn)(int fd, void *buf, size_t n);
// ...
// Hardware
int (*gpio_set_level)(int pin, int level);
int (*i2c_write)(uint8_t addr, const uint8_t *data, size_t len);
// ...
} spm_table_t;
This is SP/M’s system call interface. The SDK header (sdk/spm.h) shadows ESP-IDF function names with macros that transparently call through the jump table, enabling dual-target compilation — the same source compiles as either a transient program or native ESP-IDF firmware.
6. Concurrency & Multicore
On dual-core ESP32 (ESP32, ESP32-S3):
- Core 0: SP/M kernel, CCP shell, built-in commands, script interpreter
- Core 1: Transient programs
This means you can run a program and still interact with the shell — a deliberate design choice for hardware debugging.
On single-core variants (ESP32-C3, ESP32-C6):
- Programs run on the same core, blocking the shell until completion.
7. Command Dispatch & Shell
The CCP (Console Command Processor) is the OS shell:
- Reads lines with full VT100 editing (arrows, history, word navigation)
- Parses into arguments
- Dispatches via hardcoded
if/elsechain to built-in commands - If no built-in matches, attempts to load as transient program (
.spmfile) - Falls back to “Unknown command” if no file found
This is not a modular command system — built-ins are compiled into the kernel, not loadable modules.
8. What SP/M Does NOT Have
These absences are as important as its features:
- No MMU / memory protection — Single address space, programs can access anything
- No preemptive multitasking — Cooperative execution only
- No networking stack — Focus is local hardware debugging
- No user/supervisor mode — Everything runs at the same privilege level
- No dynamic linking — Programs are statically linked against the jump table ABI
- No process IDs or scheduling — Just “run until done”
Summary
SP/M is a single-user, single-tasking, embedded OS with a deliberately retro design philosophy. It provides just enough OS services to support interactive hardware debugging: a shell, filesystem, program loader with relocations, and a hardware abstraction layer. The jump table mechanism gives it a clean binary interface for user programs without the overhead of a full syscall trap mechanism. It trades completeness for simplicity and fast iteration during hardware bring-up.
Report B - Generated without a Lode
Prompt: explain the OS aspects of this implementation
[intermediate turns redacted for brevity]
The user asked me to explain the OS aspects of this implementation. I have gathered enough information to provide a comprehensive answer. Let me summarize the OS-like aspects of this SP/M (Script Processing Module) system:
- Kernel/Shell Architecture: It’s a single-user, single-tasking command-line OS with a shell (CCP - Console Command Processor) that runs in a loop.
- Process Model / Transient Programs: It loads and executes
.spmfiles (transient programs) via a loader with a jump table (system call interface). This is similar to CP/M or early DOS TPA (Transient Program Area) model. - Memory Management: Split IRAM/DRAM allocation for transient programs, with explicit memory regions (TPA_IRAM_SIZE, TPA_DRAM_SIZE, TPA_STACK_SIZE). Uses ESP32 heap_caps_malloc with MALLOC_CAP_EXEC for executable memory.
- Multicore/Tasking: Uses FreeRTOS tasks. Shell runs on Core 0, transient programs run on Core 1 (if dual-core). The shell blocks waiting for the transient program to complete (cooperative multitasking from the shell’s perspective).
- Virtual File System: VFS layer with mount points (/void, /sd0, /sd1, /nv0), path resolution, aliases (sys:), and CWD support.
- Hardware Abstraction Layer (HAL): Abstracts GPIO, I2C, SPI, ADC, UART, timers across ESP32 variants.
- System Call Interface (Jump Table): The
spm_table_tprovides a structured system call interface for transient programs, shadowing ESP-IDF/FreeRTOS APIs. - Scripting Engine: Built-in interpreter with lexer, parser, AST, and executor - provides an interpreted language environment.
- Line Editor: Built-in line editing for the shell.
- Boot/Initialization Sequence: NVS init, console init, VFS init, SFT init, then shell.
This is essentially a miniature operating system for ESP32, modeled after classic CP/M concepts but with modern embedded features. Let me provide a clear, structured explanation.
This project is a miniature single-user, single-tasking OS for ESP32 called SP/M. It is explicitly modeled after classic CP/M concepts (the name, “Transient Program Area,” .spm binaries, and the jump-table syscall interface), but built on top of FreeRTOS and ESP-IDF. Here are its OS aspects:
1. Kernel Architecture
The system follows a monolithic kernel design with a clear separation between the resident kernel and transient user programs:
- Resident kernel (
main.c,ccp/,exec/,vfs/,hal/): Always in memory. Handles hardware, filesystems, shell, and program loading. - Transient programs (
.spmfiles): Loaded into the TPA, executed, and then discarded.
The boot sequence in app_main() is typical of a small OS:
- Initialize NVS (non-volatile storage subsystem)
- Initialize console (UART VFS)
- Initialize VFS (mount filesystems)
- Initialize serial file transfer (SFT)
- Drop into the shell (
ccp_run())
2. Process Model: The TPA and Program Loader
SP/M implements a CP/M-style Transient Program Area (TPA) with explicit memory segmentation:
| Region | Size | Purpose | Allocation |
|---|---|---|---|
| IRAM (code) | 32 KB | .text section |
MALLOC_CAP_EXEC \| MALLOC_CAP_32BIT |
| DRAM (data) | 16 KB | .rodata, .data, .bss |
MALLOC_CAP_8BIT |
| Stack | 8 KB | Program stack | Part of FreeRTOS task |
The loader (exec/loader.c) is the core of the process model:
- Reads a structured
.spmbinary (header + sections + relocation table) - Splits code and data into IRAM (executable) and DRAM (byte-accessible)
- Applies absolute relocations to fix up addresses for the split layout
- Spawns a FreeRTOS task (
program_task) to run the program - On dual-core ESP32: Shell stays on Core 0, transient programs run on Core 1
- The shell blocks (
while (!s_exec_ctx.done)) until the program exits, then frees TPA memory
This is effectively cooperative multitasking from the shell’s perspective: only one user program runs at a time, and the kernel waits for it to finish.
3. System Call Interface (Jump Table)
SP/M provides a structured syscall interface via the spm_table_t jump table (sdk/spm.h, exec/spm_table.c). This is the only way transient programs interact with the kernel:
- Console I/O:
putchar_fn,getchar_fn - File I/O:
open_fn,read_fn,write_fn,close_fn(pass-through to POSIX/VFS) - System:
exit_fn,delay_ms_fn - Hardware: GPIO, I2C, SPI, ADC
The SDK header (spm.h) shadows ESP-IDF and FreeRTOS APIs as macros that dereference the jump table. This means the same source code can compile as either:
- A native ESP-IDF app (links against real drivers)
- A transient SP/M program (links against the jump table)
This is analogous to how DOS .COM files used INT 21h or how modern OSes use libc as a syscall wrapper.
4. Virtual File System (VFS)
The VFS layer (vfs/) provides a Unix-like namespace on top of ESP-IDF’s VFS:
- Mount points:
/void/(virtual empty),/sd0/,/sd1/(SD cards),/nv0/(internal LittleFS flash) - Path resolution: Supports aliases (
sys:), absolute paths, and relative paths with CWD - CWD tracking: The shell maintains a current working directory (
ccp_get_cwd())
This abstracts the underlying storage (SD via FAT, internal flash via LittleFS) behind a unified path interface.
5. Hardware Abstraction Layer (HAL)
The HAL (hal/hal.h) isolates the kernel from ESP32-specific peripherals, providing a consistent API for:
- GPIO (including PWM and interrupt-based “watch”)
- I2C (multi-bus)
- SPI (full-duplex, GPIO-controlled CS)
- ADC (with attenuation config)
- UART (console)
- System (chip info, reset, memory queries)
This is the standard OS HAL pattern: the kernel and transient programs talk to the HAL, and the HAL talks to ESP-IDF drivers.
6. Shell and Command Processor (CCP)
The Console Command Processor (ccp/ccp.c) is the user-facing OS shell:
- Reads lines with a line editor (
line_edit.c) - Parses commands into
argc/argv - Dispatches to built-in commands (
help,ls,cd,cat,gpio,i2c, etc.) - Falls back to transient program execution (
.spmfiles) if no built-in matches - Tracks exit codes (
last_error) like$?in Unix shells
7. Scripting Engine
Beyond binary transient programs, the OS includes a full interpreted language runtime (script/):
- Lexer, parser, AST, expression evaluator, and executor
- This makes SP/M a self-hosted environment where you can write scripts without compiling
.spmbinaries
Summary
SP/M is a real operating system in miniature. It has:
- A bootloader/initializer
- A resident kernel with HAL
- A process loader with memory management (TPA)
- A system call interface (jump table)
- A virtual file system with mount points
- A command shell
- A scripting runtime
Its architecture is closest to CP/M (transient programs, TPA, jump table) or early MS-DOS, but running on a dual-core ESP32 with FreeRTOS as its microkernel foundation.