Skip to content

Instantly share code, notes, and snippets.

View savarin's full-sized avatar

Ezzeri Esa savarin

  • San Francisco Bay Area
View GitHub Profile
@savarin
savarin / 11-the-isolate.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 11 — The Sandbox

← Back to Index

Chapter 11 — The Isolate

Introduction

Every workflow script the model authors is a potential attack surface. Chapter 10 introduced workflow scripts as agent-authored code: a string of Python that the runtime compiles and executes on each run. That script can contain arbitrary logic. It can loop forever. It can try to allocate a gigabyte of memory. If it finds a path to the host process, it can read the environment variables where the LiteLLM API keys live. Running that code in the same process as the runtime — even behind restricted builtins — is not sufficient without process-level isolation.

But isolation has costs. Every boundary you draw is a round trip, a serialization format, and a new class of failure mode. The question is not whether to isolate; it is which threats you are isolating against, what you are willing to pay, and where you draw the line. Chapter 9 drew one isolation boundary around tool execution — the `San

@savarin
savarin / 10-workflows.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 10 — Workflows

← Back to Index

Chapter 10 — Workflows

An agent that runs a single task is tractable. An agent that fans out into ten parallel subtasks — each with its own model call, its own filesystem state, its own failure modes — is a distributed system. And distributed systems fail in ways that single-process code does not: a node dies mid-fan-out, a subagent completes but its result gets lost, a retry re-executes work that already had side effects. The workflow system exists to make that distributed fan-out safe. It does so by making orchestration durable and deterministic: the control flow is code, not model-driven improvisation, and every node in the graph has a stable, replayable identity.

You have already seen, in Chapters 6 and 7, how the journal gives a single turn its durability — a monotonically advancing phase marker that tells recovery exactly how far the turn progressed before the process died. This chapter extends that idea upward. Where the j

@savarin
savarin / 09-the-sandbox-boundary.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 9 — The Sandbox Boundary

← Back to Index

Chapter 9 — The Sandbox Boundary

Every file the agent reads, every command it runs, every Python script it executes — all of it travels through one interface: SandboxApi. The interface has eleven methods. What changes between deployment modes is not the interface but the implementation behind it: local filesystem and subprocess in development, a remote control server connected over a private TCP port in production. The agent, the tools, and the turn loop never observe the difference. That topology-independence is the core design decision of the sandbox layer, and this chapter traces exactly how it is achieved.

The SandboxApi Contract

Start with the interface itself, because everything else derives from it.

@savarin
savarin / 08-tools-as-factories.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 8 — Tools as Factories

← Back to Index

Chapter 8 — Tools as Factories

A tool is where the model touches the world. The design of that touch point determines what the agent can do, what it cannot do, and — critically — what it cannot do by accident. In v1, tools were closures: they captured live context at construction time and held it forever. The design worked until it didn't — until the need to reconstruct a session from a durable record exposed that the closed-over references were gone. v2 rethinks the tool from the ground up. A tool definition is a context-free value; context enters only at session construction, through an explicit binding step. The result is a toolset that can be reconstructed by any process that has the session spec and the registry.

This chapter traces that evolution. Chapter 4 established the construction seam as the single place where a session's dependencies are assembled. Tools are assembled at that same seam. Chapter 9 covers the sandbox t

@savarin
savarin / 07-resume-and-repair.md
Last active June 27, 2026 16:51
The Rewrite: Python Edition — Chapter 7 — Resume and Repair

← Back to Index

Chapter 7 — Resume and Repair

The journal from Chapter 6 answers one question precisely: where did the turn stop? It records a phase, a stream key, a tool request, a transcript leaf pointer. What it does not do is decide what happens next. That is the question this chapter answers.

When a turn resumes after a crash, the system faces a branching problem: the submission's journal says how far the turn got, but "how far" admits multiple interpretations. Did the model finish streaming? Were tool calls partially executed? Were some results already committed to the transcript and some not? Each combination demands a different recovery strategy — and the wrong strategy either re-runs a side-effecting tool or skips a step the model still needs. classify_submission_state is the pure function that reads the durable record and names which case you are in. This chapter is about that classifier and what each classification requires.

This i

@savarin
savarin / 06-the-journal.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 6 — The Journal

← Back to Index

Chapter 6 — The Journal

A log records what happened. A journal makes a promise about what will happen next. That distinction sits at the center of this chapter.

When an agent turn crashes mid-execution — after the model has streamed a response, after tool calls have been issued, but before the transcript is committed — recovery can only succeed if there is a durable record of exactly how far the turn progressed. Not a timestamp. Not a boolean flag. A precise, monotonically advancing phase marker that tells the recovering attempt: start here, not from the beginning. The v2 journal is that record. Understanding it means understanding what durability actually guarantees in a system where turns span multiple network calls, a streaming response, and a tree-structured transcript.

Chapter 5 introduced the journal from the Coordinator's perspective — the four phases that wrap drive_run, and the state-machine view of what happens when

@savarin
savarin / 05-the-turn.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 5 — The Turn

← Back to Index

Chapter 5 — The Turn

The turn is the atom of the runtime. Everything else — sessions, coordinators, stores, workflow nodes — exists to support one thing: taking a prompt, driving the model loop to idle, and producing a result. v1 and v2 run the same inner loop. The difference is what wraps it. v1's envelope is an await: the turn is a promise, and if the process dies mid-turn, the promise disappears with it. v2's envelope is a four-phase journal: the turn is a state machine, and if the process dies at any phase, the next process knows exactly where it was.

@savarin
savarin / 04-the-single-construction-seam.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 4 — The Single Construction Seam

← Back to Index

Chapter 4 — The Single Construction Seam

The construction seam is the one place in a system where all the abstractions are real simultaneously. Every seam you declared in core/contracts.ts exists as a type; the construction root is where they become objects, wired to each other in the only order the dependency graph allows. If you can hold the construction root in your head, you can hold the whole system in your head. This chapter looks at how v1 and v2 construct themselves — what each wires, what each exposes, and why v2's construction root has sharper separation between wiring and runtime even as it adds new explicit seams.

@savarin
savarin / 03-contracts.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 3 — Contracts

← Back to Index

Chapter 3 — Contracts

When you rewrite a system, you discover which of its abstractions were load-bearing and which were accidents of the first implementation. The contracts file — core/contracts.ts in both v1 and v2 — is where that distinction becomes legible. It declares the seams: types only, no behavior, the shape you want to be able to read and pressure-test in one view. This chapter puts v1's contracts and v2's contracts side by side and asks: what survived, what was dropped, and why does the answer matter?

@savarin
savarin / 02-reading-other-peoples-runtimes.md
Last active June 27, 2026 22:01
The Rewrite: Python Edition — Chapter 2 — Reading Other People's Runtimes

← Back to Index

Chapter 2 — Reading Other People's Runtimes

Before you commit to a shape, you want evidence that the shape is right — not from first principles, but from systems that have already converged on it under real production load. Two production runtimes worth studying are Anthropic's claude-code CLI and OpenAI's codex-rs — one widely deployed, one a recent ground-up rewrite in another language by another team. They were built independently, for different models, in different languages, by teams who didn't coordinate on design. If two systems arrive at the same structure without sharing notes, that structure is probably not an accident.

This chapter describes a method — the shape audit — and what it found.

2.1 Why You Read Other Runtimes