# Deep-Dive DD-01 — Pi: The Minimal Baseline

**Course**: Master Course — Harness Engineering
**Deep-Dive**: DD-01
**Duration**: 45 minutes
**Level**: Senior Engineer and above
**Prerequisites**: Modules 0–12 (especially 0.1 thickness spectrum, 0.3 rubric + 6-phase method, Module 1 the loop, Module 2 the tool layer, Module 11 security)

> *What you get with 4 tools and a <1,000-token system prompt. Pi is the reference thin harness — every other deep-dive in the curriculum compares against it.*

---

## The load-bearing claim

**Pi is the base architecture every course in this curriculum builds on.** Course 2A builds security tools *for* it (sandboxes, scopes, approval gates that Pi omits). Course 2B *attacks* it (the OWASP ASI offensive procedures find Pi's trust-the-model posture by default). Course 3 *drops fine-tuned models into it* (the loop is unchanged; the model inside it is different). Course 4 *deploys it at scale* (the same ~80-line loop, replicated and observed). If you understand Pi — what it does, what it deliberately does not do, and why those omissions are correct *for its use case* — you understand the irreducible core every thicker harness varies on. This deep-dive is the reference reading for that core.

---

## Learning objectives

After this deep-dive, you will be able to:

1. Apply the 6-phase deep-dive methodology (Module 0.3) to Pi and produce a scored analysis card with file:line evidence.
2. **Defend Pi's thin-harness design as *correct for its use case*, not as a deficiency** — the load-bearing distinction the rest of the curriculum depends on.
3. Score Pi on the 12-module rubric (/60) with evidence, and explain why a low absolute score is the *expected* result for a deliberate thin harness, not a failure.
4. Write the Architect's Verdict and MLSecOps Relevance note for Pi in the canonical template.
5. Use Pi as the benchmark for every subsequent deep-dive — every other harness is measured against Pi's minimalism: "how much thickness does X add, and why?"
6. Articulate the three decisions Pi makes that every thicker harness should justify deviating from (the 4-tool set, the dumb-loop philosophy, the ultra-thin prompt).

---

## The subject

**Pi** is the reference thin harness. The numbers from Module 0.1:

| Metric | Value |
| --- | --- |
| Tools | 4 (`bash`, `read_file`, `write_file`, `search`) |
| System prompt | <1,000 tokens |
| Total harness code | ~1,200 lines of TypeScript |
| Permission model | Trust-the-model |
| Context management | Minimal; no active compaction |
| Memory | Ephemeral (in-context only) |

Pi is the harness you read in 30 minutes (the Module 0.1 lab) and the benchmark against which every other harness's thickness is measured. It is not a toy. It is a deliberate architectural statement: **do as little as possible in the harness; let the model do the work.** The model is the 1.6%; the harness is the 98.4% — Pi is the harness that asks how small that 98.4% can get before it stops being a harness at all.

---

## Phase 1 — First Contact

Pi is small enough to read in full. The entry point is standard. The file structure maps cleanly to the three jobs (loop, tools, safety):

- **Entry point**: the CLI handler that parses arguments and starts the loop.
- **The loop**: ~80 lines of TypeScript — a `while(true)` around `model.complete()`, with a `stopReason === "end_turn"` exit and a max-iterations guard.
- **Tool registry**: 4 tool definitions, each a JSON schema with `name`, `description`, and `input_schema`.
- **Safety layer**: the max-iterations guard and basic error handling. No per-action approval gates. No sandbox beyond the OS process.
- **Context manager**: absent. Pi relies on minimal tool output (the 4 tools return modest results) rather than active compaction. No observation masking, no JIT retrieval.
- **System prompt**: found in source, not docs. Under 1,000 tokens. Identity, instructions, policies — concise.

The license is permissive (MIT). No CLA friction.

---

## Phase 2 — Architecture Map

The loop, drawn from the Module 0.1 lab:

```
user task → [system prompt + tool defs + history] → model.complete()
                                                         │
                                          ┌──────────────┴──────────────┐
                                          │ end_turn?                   │ tool_use?
                                          │                             │
                                          ▼                             ▼
                                       return                       execute tool
                                                                       │
                                                                       ▼
                                                                   append result
                                                                       │
                                                                       ▼
                                                                  (back to loop)
                                                                  max-iter guard
                                                                  all the while
```

**Tool list** (the complete registry):

1. `bash` — run a shell command; return `stdout`/`stderr`
2. `read_file` — read file contents into context
3. `write_file` — write content to a file path
4. `search` — query a search engine; return ranked results

**Stop conditions** (2 of the 5 from Module 1.2):

1. `end_turn` — model emits no tool call (natural stop)
2. `max iterations` — hard cap (safety net)

**Missing:** token budget, error threshold, human interrupt. Pi is a personal assistant; these matter less than in enterprise. But they are absent — a scored finding.

**One traced tool call**: model emits `tool_use: read_file({path: "auth.ts"})` → harness validates name against the 4-tool registry → schema-validates `{path: string}` → executes `readFileSync("auth.ts")` → returns content → appends to history as `{role: "tool", content: ...}` → next model call. Clean, minimal, exactly Module 2's 7-step dispatch with 4 tools.

---

## Phase 3 — Design Decision Audit (12 modules)

| Module | Pattern | Tradeoff accepted | Evidence |
| --- | --- | --- | --- |
| 1 Execution Loop | ReAct (dumb-loop philosophy) | Error compounding; no lookahead | the ~80-line while loop |
| 2 Tool Design | Static, 4 tools, schema-first | Less capability without extension | the 4 tool defs |
| 3 Context Mgmt | None (relies on minimal tool output) | Context rot on long sessions | absence of compaction logic |
| 4 Memory | Ephemeral (in-context only) | Cannot do multi-session | no persistent store |
| 5 Sandboxing | None (OS process only) | Blast radius = host | no container/VM |
| 6 Permission | Trust-the-model | No per-action approval | absence of gates |
| 7 Error Handling | Minimal (let model self-correct via tool-result errors) | No taxonomy; retries possible | basic try/catch |
| 8 State | None (stateless) | Every interruption = restart | no checkpoint |
| 9 Verification | None (ship and hope) | No quality gate | absence |
| 10 Subagents | None | No parallelism/delegation | absence |
| 11 Observability | Minimal console output | Un-debuggable on long sessions | `console.log`, not structured |
| 12 Prompt Assembly | Ultra-thin (<1k tokens) | Less explicit behavior control | the system prompt |

**Three decisions I agree with**:

1. **The 4-tool set** — correct for a personal assistant. A 5th tool adds decision noise (the Vercel finding, Module 2: cutting 80% of tools improved selection accuracy). The minimum capable set is also the lowest-noise set.
2. **The dumb-loop philosophy** — co-evolves with model upgrades (the future-proof test, Module 1: does performance improve on model upgrade without harness changes? Pi passes by design because the harness adds no cleverness that could rot).
3. **The ultra-thin prompt** — delegates to the model; doesn't fight capability growth. A thick prompt over-specifies behavior the model already handles; Pi's <1k prompt gets out of the way.

**Three decisions I would make differently**:

1. **Add a token budget** (Module 1.2). Even a personal assistant can produce a runaway bill. Cheap to add; prevents the worst outcome.
2. **Add structured per-turn logging** (Module 10). The 8-field payload is trivial to add and transforms debuggability. Pi's `console.log` is below the floor.
3. **Add basic compaction** (Module 3). Pi relies on minimal tool output, but a long `bash` session can still rot context. A simple threshold-triggered summarizer would extend Pi's effective range significantly.

---

## Phase 4 — Security Audit

**Credential flow**: API key in environment variables; read at startup; passed to the model client. No isolation. An attacker who compromises the Pi process can read the key.

**Shell/exec/write/network paths**: all four tools are powerful — `bash` is full shell access; `write_file` is unrestricted; `search` makes network calls. **Blast radius of a compromised Pi process = the entire host.** Pi can read `~/.ssh`, write anywhere the process user can, and call any URL.

**Injection test (reasoned)**: Pi has no untrusted-content tagging. A file read via `read_file` that contains injected instructions would enter context as raw content. The model may comply. **Pi is vulnerable to indirect injection** (Module 2.4 Vector 1, OWASP ASI01) — *by design*; it is a thin harness that trusts the model. This is the exact surface Course 2B's SDD-B01 offensive expansion lands on first.

**The key security finding**: Pi is correct for a trusted single-user environment (personal assistant on your own machine). It is incorrect for any multi-user, multi-tenant, or untrusted-input context. The absence of sandboxing (Module 5), scoping (Module 5.3), and tagging (Module 2.4) is a deliberate tradeoff for thinness — not an oversight, but a use-case limitation. Read the OWASP ASI checklist (Course 2B Module B9) against Pi and every row that Pi omits is a row where Pi's answer is "the model handles it" — which is honest about the threat model and wrong the moment the input is untrusted.

---

## Phase 5 — Benchmark & Performance

- **Published benchmarks**: Pi does not pursue SWE-bench or similar; it is a reference architecture, not a benchmark competitor. Its "benchmark" is the future-proof test — it improves for free as the model upgrades.
- **Token profile**: low. The thin prompt (<1k tokens) and 4 small tools mean the base cost per turn is minimal. Tool outputs dominate (Module 0.3's 67.6% rule), but Pi's tools return modest results by design.
- **Cold start**: instant — it is a Node process with no sandbox to initialize.

---

## Phase 6 — Score & Synthesize

### Scoring sheet

| Module | Score (1–5) | Key decision | Tradeoff | Evidence |
| --- | --- | --- | --- | --- |
| 1 Execution Loop | 4 | ReAct dumb-loop | error compounding | the 80-line loop |
| 2 Tool Design | 5 | 4-tool schema-first | less extensibility | 4 tool defs, correct for use case |
| 3 Context Mgmt | 2 | none | context rot | absence of compaction |
| 4 Memory | 1 | ephemeral only | no multi-session | no persistent store |
| 5 Sandboxing | 1 | none | blast radius = host | no container |
| 6 Permission | 2 | trust-the-model | no gates | absence |
| 7 Error Handling | 2 | minimal | no taxonomy | basic try/catch |
| 8 State | 1 | none | no resume | no checkpoint |
| 9 Verification | 1 | none | no quality gate | absence |
| 10 Subagents | — | n/a (single-agent by design) | — | — |
| 11 Observability | 2 | console.log | un-debuggable | minimal logging |
| 12 Prompt Assembly | 5 | ultra-thin | less control | <1k token prompt |
| **TOTAL** | **25/60** | (12 modules; subagents scored 0/5 where absent) | | |

**The score is low in absolute terms because the rubric scores *production-readiness across all dimensions*.** Pi is not trying to be production-grade across all dimensions — it is deliberately thin. **The score reflects what Pi IS NOT, not a failure of what Pi IS.** A thick harness (Claude Code, Codex CLI) scores higher; Pi's value is elsewhere — the future-proof test, the legibility, the co-evolution.

### Architect's Verdict (3 sentences)

> *Pi optimizes for model-co-evolution and legibility — a ~1,200-line harness any engineer can read in an afternoon, that improves automatically as the model upgrades. It sacrifices safety, memory, and observability — accepting blast radius, statelessness, and un-debuggability as the cost of thinness. Build on Pi if your use case is a personal assistant in a trusted environment; do not build on it for multi-tenant, enterprise, or untrusted-input work.*

### MLSecOps Relevance (1 sentence)

> *Pi's defining security property is the absence of defenses: no sandboxing, no scoping, no untrusted-tagging — correct for a trusted single-user context, but a vulnerability catalog for any deployment that touches untrusted input or multiple users.*

### Three things Pi does better than any other studied harness

1. **Legibility**: ~1,200 lines. Any engineer can read it all, understand it, and modify it. No other harness in the deep-dive roster is this small.
2. **Co-evolution**: the dumb-loop philosophy + thin prompt mean Pi benefits directly from every model upgrade. The future-proof test (Module 1) is Pi's reason for being.
3. **Conceptual clarity**: Pi is the purest expression of "the harness does only what it must." Every other harness adds complexity Pi demonstrates is optional.

### Three things I would fix if I forked Pi

1. Add the token-budget stop condition (Module 1.2) — cheap, prevents runaway cost.
2. Add the 8-field per-turn observability payload (Module 10) — transforms debuggability.
3. Add a basic compaction threshold (Module 3) — extends effective range for longer sessions.

These three additions would move Pi from "minimal baseline" to "minimal production" without compromising its thinness.

---

## How the rest of the curriculum reads Pi

This is the threading note. Every course after this one assumes you have read Pi and understands *why* it is thin.

- **Course 2A — Security Harnesses**: builds the layers Pi omits. Where Pi says "trust the model," Course 2A builds the sandbox (Module 5), the filesystem scope (Module 5.3), the approval gate (Module 6). The Course 2A deep-dives (security-hardened harnesses) are Pi + the missing safety layer, and their scores on Modules 5–6 are where they diverge from Pi's 1/2.
- **Course 2B — Securing & Attacking Harnesses and LLMs**: attacks Pi. The SDD-B01 offensive expansion (OWASP ASI Top 10) reads Pi's trust-the-model posture as the default surface — no taint gate means ASI01 drift is trivial; no sanitizer means ASI07 output-as-input is trivial; no principal binding means ASI10 inter-agent trust escalation is trivial. Pi is the *un-hardened baseline* every Course 2B procedure is run against first.
- **Course 3 — LLM Fine-Tuning**: drops a fine-tuned model into Pi's loop. The loop is unchanged — the future-proof test means the harness does not need to know the model changed. Course 3's contribution is *inside* the model; Pi's contribution is the stable loop around it.
- **Course 4 — Enterprise Platforms**: deploys Pi at scale. The same ~80-line loop, replicated across a fleet, with the observability (Module 10) and state-checkpointing (Module 8) layers Course 4 adds on top. Pi is the unit of deployment.

Read Pi once, here. You will refer back to it in every subsequent course.

---

## Anti-patterns

### "Pi scores 25/60, so it is a bad harness"
The rubric scores production-readiness across all dimensions. Pi is deliberately thin — its value is legibility and co-evolution, not breadth. The low score is the *expected* result for a deliberate thin harness, not a failure. Cure: read the score alongside the use case. A 25/60 harness that is correct for personal-assistant-in-trusted-environment is a better fit than a 55/60 harness that brings enterprise machinery to a task that does not need it.

### "Pi has no sandbox — add one and it is production-ready"
Adding a sandbox changes the threat model Pi was designed for. Pi's trust-the-model posture is correct for a single user on their own machine; adding a sandbox without also adding scoping, approval gates, and observability gives you the cost of the sandbox without the benefit. Cure: if you need a sandbox, you need the full security layer (Course 2A), not just one component. Fork Pi, but fork it coherently.

### "The thin prompt is lazy engineering"
The <1k token prompt is a deliberate delegation to the model. A thick prompt over-specifies behavior the model already handles and rots when the model upgrades (the future-proof test fails). Cure: treat the thin prompt as the co-evolution mechanism it is. Add prompt content only when the model demonstrably fails without it, and remove it when the model outgrows it.

### "Pi's 4 tools are too few — add more for capability"
The Vercel finding (Module 2) showed that cutting 80% of tools *improved* selection accuracy. A 5th tool adds decision noise; the minimum capable set is also the lowest-noise set. Cure: keep the toolset minimal. If a new capability is needed, prefer composing the existing 4 tools over adding a 5th. The 4-tool philosophy is not a limitation; it is a noise-reduction strategy.

---

## Key terms

| Term | Definition |
| --- | --- |
| **Trust-the-model** | Pi's permission model: the model is trusted to act; no per-action gates. Correct for trusted single-user; wrong for untrusted input. |
| **The 4-tool philosophy** | `bash`, `read_file`, `write_file`, `search` — the minimum capable set, also the lowest-noise set (Vercel finding). |
| **Future-proof test** | Does performance improve on model upgrade without harness changes? Pi passes by design — the dumb loop and thin prompt add no cleverness that can rot. |
| **Dumb-loop philosophy** | The ReAct loop with no lookahead, no planning, no reflection. Error-compounding risk, but co-evolves with the model. |
| **The 25/60 score** | The expected score for a deliberate thin harness. The score reflects what Pi IS NOT, not a failure of what Pi IS. |
| **Co-evolution** | Pi improves automatically as the model upgrades — the harness adds no cleverness that could rot. The opposite of over-engineering. |

---

## Lab exercise

See `07-lab-spec.md`. You re-score Pi against the 12-module rubric with the full Modules 1–12 lens, trace one tool call through the 7-step dispatch, and justify the three changes you would make if you forked Pi toward "minimal production."

---

## References

1. **Pi source code** — the primary reference for this deep-dive (~1,200 lines of TypeScript, readable in 30 minutes per the Module 0.1 lab).
2. **Module 0.1 — What is a Harness** — the thickness spectrum; Pi as the thin reference point; the 30-minute read lab.
3. **Module 0.3 — The Rubric and 6-Phase Method** — the methodology applied here; the /60 scoring sheet.
4. **Module 1 — The Execution Loop** — the dumb-loop philosophy; the future-proof test; the 5 stop conditions (Pi implements 2).
5. **Module 2 — Tool Design** — the 4-tool set and the Vercel finding that validates keeping it small.
6. **Module 5 — Sandboxing** — the layer Pi omits; the blast-radius finding.
7. **Module 10 — Observability** — the 8-field per-turn payload Pi omits; the console.log finding.
8. **Module 11 — Security** — the security audit framing (no defenses = the finding).
9. **Every subsequent deep-dive (DD-02 through DD-21)** — compares against Pi as the baseline; the "how much thickness does X add, and why?" question originates here.
10. **Course 2B SDD-B01 — OWASP ASI Offensive Expansion** — the red-team playbook that reads Pi's trust-the-model posture as the default attack surface.
