What can an LLM build with only 32 CPU instructions? Picos is a new agent harness that gives large language models a custom 32-bit CPU called smol32 with only 32 instructions (0x00–0x1f), 16 registers (r0–r15), a single flat RAM array, raw disk storage, and a 256 × 192 RGB332 display, with no guest OS, filesystem, shell, allocator, programming language, or window system. The harness runs either a pure-Rust agent loop using direct ChatGPT subscription OAuth (picos login --direct) that exposes only 9 virtual machine tools, or delegates to the Codex CLI inside a read-only sandbox restricted to the same 9 MCP machine tools, letting users cap turns, CPU clock, RAM, disk, and total cycle allowance. The project's stated goal is to observe how different models fit code, data, stack, and graphics into fixed memory when the CPU offers no floating-point ops, SIMD, hardware interrupts, memory protection rings, or graphics syscalls. Give an LLM a small computer and watch it build from assembly. Picos starts with a custom 32-bit CPU smol32 , fixed RAM, raw storage, and a 256 × 192 pixel display. There is no guest OS, filesystem, shell, allocator, programming language, or window system. Everything has to be built from machine instructions. The goal is to see what different models do when given tight constraints. From the CLI or the web UI, you can cap the number of turns, hide or show the remaining turn budget, and limit the CPU clock, RAM, disk, and total cycle allowance. With only bare machine instructions and fixed capacity, models have to figure out their own ways to fit code, data, stack, and graphics into memory. ┌───────────────────────────────────────────────┐ │ Agent / LLM Provider │ │ Direct ChatGPT Auth or Codex CLI │ └───────────────────────┬───────────────────────┘ │ JSON-RPC / MCP ┌───────────────────────▼───────────────────────┐ │ Picos Harness & MCP Bridge │ │ src/strict.rs / src/mcp.rs │ └───────────────────────┬───────────────────────┘ │ Machine Tools ┌───────────────────────▼───────────────────────┐ │ Virtual Machine │ │ src/vm.rs │ │ • smol32 CPU r0–r15, PC, comparison state │ │ • Flat mutable RAM code, data, stack, VRAM │ │ • Display 256×192 RGB332 @ VIDEO BASE │ │ • Raw Disk Storage │ │ • I/O Ports: Serial, Keyboard, Disk, Cycles │ └───────────────┬───────────────────────┬───────┘ │ │ ┌───────────────────▼──┐ ┌──────────▼─────────────────┐ │ Assembler / Disasm │ │ HTTP Server & Web Observer │ │ src/assembler.rs │ │ src/server.rs │ │ src/disassembler.rs │ │ public/index.html │ └──────────────────────┘ └────────────────────────────┘ - Strict Execution Boundary --strict : Runs a pure-Rust agent loop using direct ChatGPT subscription OAuth picos login --direct . It exposes only the 9 virtual machine tools, with no host shell, filesystem, Python, or Node.js. - Legacy Codex Runner : Delegates orchestration to the Codex CLI picos login inside a read-only sandbox restricted to the same 9 MCP machine tools. | Component | Specification | |---|---| | CPU | Custom 32-bit unsigned ISA smol32 , 16 registers r0 – r15 , byte-addressed PC, comparison flag | | Instruction Encoding | Fixed 8-byte instructions opcode, dest reg, operand kind, reserved zero byte, 32-bit immediate/reg | | Stack | r15 serves as the descending stack pointer, initialized on reset to VIDEO BASE | | RAM | Single flat byte array shared by code, data, stack, and framebuffer self-modifying code works natively | | Display | 256 × 192 RGB332 pixels 49,152 bytes mapped at VIDEO BASE = RAM BYTES - 49152 | | Disk | Fixed raw byte array accessed byte-by-byte via I/O ports; persists across machine reboots | | Virtual Clock | Configured in MHz 1 MHz = 1,000,000 cycles/sec ; deterministic per-instruction cycle costs | The entire CPU supports just 32 instructions 0x00 – 0x1f . There are no floating-point ops, SIMD instructions, hardware interrupts, memory protection rings, or graphics syscalls. The idea is to keep the primitives as small and transparent as possible, then see how much complexity an agent can build on top of them, from drawing bitmap fonts pixel-by-pixel in VIDEO BASE to building shells, file structures, or self-hosted compilers in flat RAM. | Category | Instructions | Description | |---|---|---| | Control | nop , halt , yield | No-op, stop CPU until reboot, or pause slice and resume at next instruction | | Move & Arithmetic | mov , add , sub , mul , div , mod | 32-bit unsigned register/immediate assignment and wrapping arithmetic | | Bitwise & Shifts | and , or , xor , shl , shr | Bitwise logic and logical bit shifts shift count uses low 5 bits | | Memory | load8 , load32 , store8 , store32 | Byte and 32-bit little-endian loads/stores to flat RAM | | Compare & Branch | cmp , jmp , je , jne , jlt , jle , jgt , jge | Unsigned comparison and conditional/unconditional jumps | | Stack & Calls | call , ret , push , pop | Subroutine calls and stack operations using r15 | | Device I/O | in , out | Read or write device ports 0 – 4 | Assembler directives are equally minimal: .equ , .byte , .word , .ascii , .asciz , and .space , along with built-in constants RAM BYTES , DISK BYTES , VIDEO BASE , VIDEO WIDTH , VIDEO HEIGHT . See docs/ISA.md https://github.com/AlwaysFocus/picos/blob/main/docs/ISA.md for exact binary encodings and per-instruction cycle costs. | Port | in rD, port Read | out rV, port Write | |---|---|---| | 0 | Returns 0 | Appends low byte of rV to serial output retains last 16,384 bytes | | 1 | Dequeues next UTF-8 keyboard byte 0xFFFFFFFF if empty | Faults CPU | | 2 | Reads current disk byte cursor | Sets disk byte cursor 0..=DISK BYTES | | 3 | Reads disk byte at cursor and advances cursor | Writes low byte of rV to disk at cursor and advances cursor | | 4 | Reads low 32 bits of lifetime cycle counter | Faults CPU | The agent interacts with the machine exclusively through 9 narrow tools defined in src/mcp.rs https://github.com/AlwaysFocus/picos/blob/main/src/mcp.rs : | Tool | Role | |---|---| | machine info | Read hardware configuration, register state, cycle usage, bootstrap rules, and the full ISA reference. | | machine screen | Capture the current guest framebuffer 256 × 192 as a PNG image. | | machine assemble | Cross-assemble smol32 source and install the binary into guest disk and RAM disabled after sealing . | | machine write | Inject raw bytes into guest RAM or disk during bootstrap disabled after sealing . | | machine run | Execute up to 2,000,000 cycles in a single slice and return CPU state and serial output. | | machine inspect | Read up to 4,096 bytes from guest RAM or disk. | | machine input | Queue up to 4,096 bytes of UTF-8 keyboard input for Port 1. | | machine reset | Reboot the guest from the disk boot image clears RAM/CPU while preserving disk, seal state, and lifetime cycles . | | machine seal | Permanently disable machine assemble and machine write so all further work happens strictly inside the guest via keyboard input and guest code. | cargo install --path . --bin picos Authenticate for strict mode direct ChatGPT OAuth picos login --direct picos login --direct status picos models Alternatively, run picos login or picos login --device-code for the Codex-backed runner . picos new terminal --strict --cpu 300 --ram 24 --storage 200 \ --model gpt-6-luna --prompt "build a terminal" A keyword syntax is also supported: picos new terminal strict cpu 300 ram 24 storage 200 \ model gpt-6-luna prompt "build a terminal" picos stays in the foreground, starts the local observer server, opens your browser, and begins the first agent turn. Press Ctrl+C at any time to save the machine state and stop the agent cleanly. List saved experiments under ~/.picos/experiments picos list Open the saved machine in the observer without starting inference picos resume terminal Resume and start a new agent turn with an updated prompt picos resume terminal --prompt "Continue building the terminal and test it." | Flag | Description | Default | |---|---|---| | --cpu