# Diagrams — DD-17: PicoClaw — The Edge-Hardware Harness

**Deep-Dive**: DD-17 — PicoClaw
**Diagram count**: 5
**Tool**: Mermaid (primary). Each diagram validated in [Mermaid Live Editor](https://mermaid.live).

---

## Diagram 1 — The Hardware-Native Agent (the differentiator)

**Type**: Layered architecture with hardware boundary
**Purpose**: The single orientation diagram. Shows PicoClaw's defining contribution: the agent kernel talks DIRECTLY to physical hardware through I2C/SPI/Serial tools. No other harness in the roster has this boundary. The MaixCAM channel receives image frames over TCP and the agent analyzes them with vision models.
**Reading the diagram**: Top = the thin agent kernel (tiny Markdown prompts, ~22 tools, append-only JSONL). Middle = the hardware tools (I2C/SPI/Serial with validated writes). Bottom = the Sipeed physical hardware the agent drives. The arrow from kernel through tools to hardware is the load-bearing differentiator.

```mermaid
flowchart TB
  subgraph KERNEL["THIN AGENT KERNEL (Go)"]
    SOUL["SOUL.md — 351 bytes"]
    AGENT["AGENT.md — 1,278 bytes"]
    TOOLS["~22 tools"]
    JSONL["Append-only JSONL memory"]
  end
  subgraph HARDWARE["HARDWARE TOOLS — the differentiator (pkg/tools/hardware/)"]
    I2C["i2c tool<br/>7-bit addr validation (0x03-0x77)<br/>256 byte cap per transaction<br/>writes require confirm: true"]
    SPI["spi tool<br/>Mode 0-3<br/>4096 byte cap per transaction<br/>writes require confirm: true"]
    SERIAL["serial tool<br/>per-OS implementations"]
  end
  subgraph PHYSICAL["SIPEED PHYSICAL HARDWARE"]
    CAM["MaixCAM AI camera<br/>sends frames via TCP"]
    BOARD["LicheeRV Nano<br/>RISC-V SBC ($10)"]
    KVM["NanoKVM"]
  end

  KERNEL -->|reads/writes| HARDWARE
  HARDWARE -->|drives peripherals<br/>reads sensors| PHYSICAL
  CAM -->|sends image frames| KERNEL

  PRINCIPLE["The ONLY harness that physically interacts with the world.<br/>I2C/SPI/Serial are first-class tools, not afterthought plugins.<br/>This is why PicoClaw exists."]

  PHYSICAL --> PRINCIPLE

  style KERNEL fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
  style HARDWARE fill:#14141f,stroke:rgba(240,168,104,0.5),color:#e4e4e8
  style PHYSICAL fill:#14141f,stroke:rgba(240,128,128,0.5),color:#e4e4e8
  style SOUL fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style AGENT fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style TOOLS fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style JSONL fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style I2C fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style SPI fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style SERIAL fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style CAM fill:#08080c,stroke:rgba(240,128,128,0.3),color:#f08080
  style BOARD fill:#08080c,stroke:rgba(240,128,128,0.3),color:#f08080
  style KVM fill:#08080c,stroke:rgba(240,128,128,0.3),color:#f08080
  style PRINCIPLE fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
```

---

## Diagram 2 — Turn-Boundary Context Trimming

**Type**: Sequential turns with a budget gate
**Purpose**: Shows PicoClaw's context-management insight. The proactive budget check runs BEFORE the LLM call. When over budget, trimming cuts at safe Turn boundaries — a tool-call sequence (assistant+ToolCalls → tool results) is never split. This is the same insight as Hermes's context management, implemented in Go.
**Reading the diagram**: Three complete turns flow into a budget check. When over budget, trimming keeps complete turns and never orphans a tool_call from its result. Splitting mid-sequence breaks the model; PicoClaw pays the cost of doing it right.

```mermaid
flowchart LR
  subgraph TURN1["TURN 1 (complete)"]
    direction TB
    U1["user msg"]
    M1["LLM iterations"]
    R1["response"]
    U1 --> M1 --> R1
  end
  subgraph TURN2["TURN 2 (complete — tool sequence)"]
    direction TB
    U2["user msg"]
    TC["assistant + ToolCalls"]
    TR["tool results"]
    R2["response"]
    U2 --> TC --> TR --> R2
  end
  subgraph TURN3["TURN 3 (complete)"]
    direction TB
    U3["user msg"]
    M3["LLM iterations"]
    R3["response"]
    U3 --> M3 --> R3
  end

  BUDGET["isOverContextBudget?<br/>msg tokens + tool-def tokens + output reserve"]
  TRIM["trimHistoryToFitContextWindow<br/>cuts at TURN BOUNDARIES"]
  KEEP["Keeps complete turns<br/>Never splits tool_call/result pairs<br/>tool sequence stays intact"]

  TURN1 --> BUDGET
  TURN2 --> BUDGET
  TURN3 --> BUDGET
  BUDGET -->|over budget| TRIM
  TRIM --> KEEP
  BUDGET -->|under budget| PASS["proceed to LLM call"]

  PRINCIPLE["Splitting mid-sequence breaks the model.<br/>PicoClaw pays the cost of doing it right:<br/>cut at Turn boundaries, never inside a tool call."]

  KEEP --> PRINCIPLE

  style TURN1 fill:#14141f,stroke:rgba(94,234,212,0.4),color:#e4e4e8
  style TURN2 fill:#14141f,stroke:rgba(240,168,104,0.5),color:#e4e4e8
  style TURN3 fill:#14141f,stroke:rgba(94,234,212,0.4),color:#e4e4e8
  style U1 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style M1 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style R1 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style U2 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style TC fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style TR fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style R2 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style U3 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style M3 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style R3 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style BUDGET fill:#08080c,stroke:rgba(240,168,104,0.4),color:#f0a868
  style TRIM fill:#08080c,stroke:rgba(240,168,104,0.4),color:#f0a868
  style KEEP fill:#08080c,stroke:rgba(130,224,170,0.4),color:#82e0aa
  style PASS fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style PRINCIPLE fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
```

---

## Diagram 3 — The Novel Hardware Attack Surface

**Type**: Two-track comparison showing the gap
**Purpose**: The security diagram. Shows why the confirm gate on writes is necessary but insufficient. A prompt-injected agent can silently READ sensors and ENUMERATE devices without triggering the write confirm gate — which may be enough to exfiltrate physical-environment data.
**Reading the diagram**: Top = the write path (gated by confirm: true — necessary defense). Bottom = the read path (UNGATED — a prompt-injected agent reads every sensor silently). The gap is the fix PicoClaw needs: ZeroClaw-level autonomy gating on ALL hardware interactions, not just writes.

```mermaid
flowchart TB
  subgraph WRITE["WRITE PATH — gated (necessary defense)"]
    direction LR
    W1["Agent emits<br/>i2c write to addr 0x48"]
    W2["confirm: true<br/>required"]
    W3["Operator approves<br/>write executes<br/>256 byte cap enforced"]
    W1 --> W2 --> W3
  end
  subgraph READ["READ PATH — UNGATED (the insufficiency)"]
    direction LR
    R1["Prompt-injected agent<br/>emits i2c read"]
    R2["NO confirm gate<br/>NO approval required"]
    R3["Agent silently reads<br/>EVERY sensor on the bus<br/>exfiltrates physical-env data"]
    R1 --> R2 --> R3
  end

  GAP["THE FIX = ZeroClaw-level autonomy gating (DD-16) on ALL hardware interactions.<br/>Treat hardware tools as medium-to-high risk.<br/>Require explicit approval for READS, not just writes.<br/>Add an audit trail. The confirm-on-writes-only gate<br/>is necessary but insufficient."]

  WRITE --> GAP
  READ --> GAP

  style WRITE fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
  style READ fill:#14141f,stroke:rgba(240,128,128,0.5),color:#e4e4e8
  style W1 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style W2 fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style W3 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style R1 fill:#08080c,stroke:rgba(240,128,128,0.3),color:#f08080
  style R2 fill:#08080c,stroke:rgba(240,128,128,0.3),color:#f08080
  style R3 fill:#08080c,stroke:rgba(240,128,128,0.4),color:#f08080
  style GAP fill:#08080c,stroke:#f0a868,stroke-width:1.5px,color:#f0a868
```

---

## Diagram 4 — Thin Kernel vs Thick Ecosystem

**Type**: Two-column comparison
**Purpose**: Resolves the "ultra-lightweight" misconception. PicoClaw is thin at the agent kernel (runs on $10 hardware) but thick in the ecosystem (the desktop use case wants everything). The two are decoupled — edge builds shed the thick ecosystem. The "ultra-lightweight" label describes runtime footprint, not codebase size.
**Reading the diagram**: Left = the thin kernel (tiny Markdown prompts, ~22 tools, append-only JSONL — this is what runs on edge hardware). Right = the thick ecosystem (20+ channels, MCP, skills, voice, WebRTC — this is what the desktop build carries). The total codebase is 868 files, ~218k LOC.

```mermaid
flowchart LR
  subgraph THIN["THIN AGENT KERNEL — runs on $10 hardware"]
    direction TB
    T1["Tiny Markdown prompts<br/>SOUL.md 351 bytes<br/>AGENT.md 1,278 bytes"]
    T2["~22 tools<br/>(incl. hardware-native)"]
    T3["Append-only JSONL memory<br/>64 sharded mutexes"]
    T4["Turn-boundary trimming<br/>LoCoMo benchmark"]
    T1 --> T2 --> T3 --> T4
  end
  subgraph THICK["THICK ECOSYSTEM — the desktop build"]
    direction TB
    K1["20+ channels<br/>10+ LLM providers"]
    K2["MCP client + skills marketplace"]
    K3["Subagents, cron, hooks<br/>(observer/interceptor/approval)"]
    K4["React dashboard, system-tray<br/>voice (ASR/TTS), WebRTC"]
    K1 --> K2 --> K3 --> K4
  end

  NOTE["Total codebase: 868 files, ~218k LOC.<br/>'Ultra-lightweight' = runtime footprint, not codebase size.<br/>Edge builds shed the thick ecosystem.<br/>The two layers are decoupled."]

  THIN --> NOTE
  THICK --> NOTE

  style THIN fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
  style THICK fill:#14141f,stroke:rgba(240,168,104,0.5),color:#e4e4e8
  style T1 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style T2 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style T3 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style T4 fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style K1 fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style K2 fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style K3 fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style K4 fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style NOTE fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
```

---

## Diagram 5 — Append-Only JSONL Memory (crash-safe short-term store)

**Type**: File-level architecture with the skip-offset pattern
**Purpose**: Shows PicoClaw's short-term memory design. Each session = two files: a JSONL of messages (one per line) and a meta.json summary. Messages are never physically deleted — TruncateHistory bumps a skip offset. This is crash-safe and fast. 64 sharded mutexes handle concurrent session access.
**Reading the diagram**: Left = the JSONL file (append-only, one message per line, never deleted). Right = the meta.json (summary + truncation offset). The skip offset is the load-bearing mechanism: it lets the harness logically truncate without physically deleting, which is crash-safe.

```mermaid
flowchart LR
  subgraph SESSION["SESSION — two files per session"]
    direction TB
    JSONL["{key}.jsonl<br/>one message per line<br/>APPEND-ONLY<br/>messages NEVER physically deleted"]
    META["{key}.meta.json<br/>summary<br/>truncation offset (skip)"]
  end

  APPEND["APPEND path<br/>new message → append line to .jsonl<br/>crash-safe: partial line = ignored on recovery"]
  TRUNCATE["TRUNCATE path<br/>TruncateHistory bumps skip offset in meta.json<br/>messages stay in .jsonl but are skipped on read<br/>NO physical deletion"]

  SESSION --> APPEND
  SESSION --> TRUNCATE

  CONCURRENCY["64 sharded mutexes<br/>for concurrent session access<br/>sessions sharded by key hash"]

  APPEND --> CONCURRENCY
  TRUNCATE --> CONCURRENCY

  PRINCIPLE["Crash-safe by design.<br/>Append-only writes never corrupt existing lines.<br/>Truncation is logical (skip offset), not physical.<br/>A process kill mid-write loses at most one line."]

  CONCURRENCY --> PRINCIPLE

  style SESSION fill:#14141f,stroke:rgba(94,234,212,0.5),color:#e4e4e8
  style JSONL fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style META fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style APPEND fill:#08080c,stroke:rgba(94,234,212,0.3),color:#5eead4
  style TRUNCATE fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style CONCURRENCY fill:#08080c,stroke:rgba(240,168,104,0.3),color:#f0a868
  style PRINCIPLE fill:#08080c,stroke:#5eead4,stroke-width:1.5px,color:#5eead4
```

---

## Validation notes

- All five diagrams use the course design system colors: `#14141f` panel fill, `#08080c` deep background for nested nodes, `#5eead4` teal accent for input/state surfaces and principle nodes, `#f0a868` warn for the permission/tool structural surfaces, `#f08080` danger for the output/resource surfaces and attack/ungated nodes. `#82e0aa` ok for the safe/correct path. `#e4e4e8` / `#9494a0` for text.
- Paste each into [Mermaid Live Editor](https://mermaid.live) to render. All use stable Mermaid syntax (`flowchart TB/LR`, `subgraph`, `direction TB/LR`) supported in current Mermaid (v10.4+).
- For the slide deck (artifact 03), these are rendered as static captures from Mermaid Live, inlined into reveal.js.
- The teal/warn/danger color coding is consistent across diagrams: teal = the input/state semantic surface and the principle nodes; warn (orange) = the tool/permission structural surface and the gap/fix nodes; danger (red) = the attack/ungated/physical-resource surface. This mapping is load-bearing — it lets the reader track which boundary a node belongs to across all five diagrams.
