You extract a reusable procedure from an agent trace by compiling it, not by summarizing it. Rote runs five operations on a successful trace. It filters the failed steps, reifies hardcoded values into parameters, resolves the dependencies between steps, fingerprints the API contract, and generates a runnable program. The output is a Play.
People searching for this sometimes call it trajectory distillation; the mechanism is the same.
The distinction from summarizing matters because a summary asks a model to describe what happened. A compiler reads what happened. Given the same trace and the same parameter decisions, the compile produces the same Play, and no reasoning tokens are spent on it.
The trace itself is a record of one environment on one day. That is why the sections below spend as much time on what breaks as on what compiles.
The trace has to be made of references before it can be compiled
A trace of pasted payloads is a transcript. A trace of references is a graph. Rote stores every API response, page snapshot, and process record in a workspace and gives each one an address: @1, @2, @3. When the agent uses a field from @1 in the request that produces @2, the workspace records that edge.
The example below shows a three-step trace. Notice that step 6 reads from @1 and never re-calls the API.
#3 rote POST /github '{...}' -s @1
#6 rote @1 '.repos[0].id' -s repo_id
#7 rote POST /github '{"repo": "$repo_id", ...}' -s @2The edge from @1 to @2 through repo_id is the dependency the compiler needs. Without references there is nothing to resolve.
Operation 1: filter removes what did not work
An exploratory run contains retries, wrong endpoints, and dead ends. The filter drops every step that errored and every step the agent marked as skipped. Failed attempts stay in the workspace as evidence; they do not enter the Play.
Success does not say which surviving steps were necessary. Resolve, two operations later, uses the reference edges to find steps that nothing consumed. The agent decides whether each one was a check worth keeping or noise to drop.
Operation 2: reify turns values into typed parameters
The recorded run used one repository name, one date range, one account. Reify replaces those literals with typed parameters that the next runner supplies. Rote rejects a release that still contains a hardcoded value where a parameter belongs. Such a Play only works for the person who recorded it.
The detector finds literals. It cannot know which literals are inputs and which are constants of the method. The agent makes that call, and the test runs at the end catch the ones it gets wrong.
Operation 3: resolve orders the steps and finds the parallelism
Resolve reads the reference edges and builds a directed acyclic graph. Steps with no dependency between them land on the same level and can run in parallel. Steps that consume an earlier output wait for it. The graph is the execution plan.
Operation 4: fingerprint binds the Play to an API contract
The Play records a fingerprint of the API it was built against: the canonical structure of the operations it calls, hashed with SHA-256. When the Play runs later, Rote compares the live contract to the fingerprint. A mismatch stops the run and reports drift instead of executing against an API that changed.
The fingerprint covers API operations only. A browser step has no schema to hash and a shell command has no contract. For those, the Play records preconditions and checks them before running: a page reaching a ready state, or a command being present on the machine.
Operation 5: generate emits the runnable program
The final operation writes the Play. It contains a step graph with declared inputs, a read/write contract, and the required credentials named but never included. It also carries a presentation that reports completed, failed, blocked, skipped, or degraded work. Rote turns a successful agent run into an inspectable, repeatable Play that can travel across harnesses, models, machines, and teams.
Four conditions make a trace uncompilable
Not every successful run can become a Play. Rote scores workspace health and refuses to compile a dirty one. Four conditions cause most refusals.
- The agent pasted payloads instead of holding references. With no edges, resolve has nothing to order.
- The run overwrote variables or repeated the same call with different results. The compiler cannot tell which value the method depends on.
- The work ran outside Rote. A command run in a bare shell or a call made through another tool leaves no trace to compile.
- The run leaned on state the trace does not carry. A browser that was already logged in, a file left by an earlier run, or a variable set by hand. Rote records declared dependencies and the browser profile each step used; anything undeclared will not reproduce on another machine.
The fix for the first three is the same. Route the work through Rote from the first step, and the trace compiles. You can check before compiling:
rote workspace health failed-deploysThe score runs from 0 to 100. A high score means skipped steps, repeated calls, or overwritten variables, and the compiler will refuse.
The save decision survives a context reset
A long run often outlives the agent's context window. Rote anchors the "keep this?" decision on disk as a pending Play, so a compaction or a fresh conversation does not lose it:
rote play pending show failed-deploys
rote play pending save failed-deploysFrom the Play sidekick the same step is one line: $play settle cap_<handle> <what the run did>. The sidekick reads the pending trace, not the conversation, and refuses to settle work that was never recorded.
Test the Play before you release it
A compiled Play is a draft until it runs with inputs the original run never saw. Run it with two or three parameter variants. If the output shape holds, release it; the release gets a version and a URI. If a variant fails, the trace carried an assumption that reify missed, and the parameter list needs another entry. If it fails on another machine, the fourth condition above is usually the reason.
rote play run my-play month=2
rote play run my-play month=7
rote play lint my-play
rote play release my-playQuestions people ask
Does extraction use a model?
No. The five operations are deterministic. A model discovers the path; the compiler keeps it.
Can I extract a procedure from a run I did last week without Rote?
No. Extraction needs the reference graph that Rote records while the work happens. There is no way to reconstruct it from a transcript after the fact.
What if the trace mixes API calls, browser steps, and shell commands?
They compile together. A page snapshot, an API response, and a process record are peers in the same workspace and share the same addressing.
How large is the saved Play compared with the trace?
The trace holds every response in full. The Play holds the step graph, parameters, and contract. In one measured run, replaying the Play cost about 300 tokens against about 15,000 for the original discovery.
This essay is one of five on turning a run into a reusable procedure
Start with the overview, How a successful AI agent run becomes a reusable procedure. The other essays each take one question further:
- Agent skills, workflows, prompts, and Plays remember different things: which container to use for what must survive the next run.
- Agent procedure memory survives a model change only as a program: why a Play runs from any model and stops when the API drifts.
- Share an agent workflow with a teammate without sharing a credential: what travels with a Play URI and what stays on the runner's machine.
Install the Play sidekick and try this on your own agent
One command installs the Play sidekick, installs Rote when it is missing, and wires the skill into the agent apps it finds on your machine. It runs on macOS and Linux, and on Windows inside WSL2.
curl -fsSL https://getrote.dev/playoffs/install.sh | shRestart your agent app, type $play (or /play in Claude Code), and run the Hello Play. It uses public data, needs no credentials, and declares no writes.
Compile the next trace instead of describing it
The next time an agent finishes a task you will ask for again, do not write down what it did. Check that the run went through Rote, then let Rote compile the trace. The description would have rotted; the Play runs.