# 8 · The workspace canvas, CAUs, and the DAG underneath

> **Where you are in the journey:** you can run, use, and create plays, and you've met all three reaches. This is the deepest section — the substrate that makes crystallization *possible* rather than magical. Read it when you want to know why the product works, not just how.

## The primitive: Context Addressable Units

The product's definition, verbatim:

> *"Every request/response pair that passes through rote lands on disk as a **Context Addressable Unit** — @1, @2, @3. These are not logs. They are persistent, queryable artifacts."*

Four properties make a CAU more than a saved response:

| Property | Meaning |
|---|---|
| **Immutable once created** | `@2` is `@2` forever; re-running creates `@5`, it never rewrites history |
| **Queryable without re-execution** | read any field out of it, any number of times, at zero API cost |
| **Typed by origin** | an adapter call, a process capture, and a page snapshot carry their provenance |
| **Linked by dependency** | when a request *references* an earlier response, that link is recorded |

The filesystem analogy is deliberate: CAUs are to context what inodes are to files — stable references that can be stored, queried, composed, and versioned. The `@N` you see in the terminal is the address.

## The workspace: a flight recorder

> *"A rote workspace is a flight recorder."*

A workspace (product surface name: **canvas**) is one addressing space that all three reaches write into. Its life is a handful of commands:

```bash
rote init my-task --seq                # open the recorder
rote proc run …                        # explore — every call lands as @N
rote browse …
rote query @N '<jq>' -r                # read fields by reference
rote query schema @N                   #   (don't guess shapes — ask)
rote play pending write my-task …      # anchor reusable results
rote workspace export my-task …        # crystallize (section 3)
rote play pending discard my-task      # tidy when done
```

Two query habits that pay off immediately:

```bash
# MCP-style responses wrap JSON in text — unwrap with fromjson
rote query @1 '.content[0].text | fromjson | .items[0].name' -r

# save a scalar for reuse in later requests as $pr_number
rote query @2 '.number' -s pr_number
```

Every `query` read is itself recorded — with the tokens the *source* response would have cost versus the tokens the *result* actually cost. The gap is the point: a 40k-token API response read three times by reference costs three field-reads, not 120k tokens of context.

## The bridge: a trace of references IS a dataflow graph

Here is the sentence the whole product balances on:

> *"A trace made of references **is a dataflow graph**. The record of what happened is, by construction, a program that can happen again."*

Walk it slowly, because it explains everything you did in section 3:

1. You fetched a package record → `@1`.
2. You fetched download counts → `@2`. Nothing about `@2` referenced `@1` — they're **independent**.
3. You composed a report using `@1{.dist-tags.latest}` and `@2{.downloads}` → `@3` **depends on both**, and the recorded references say *exactly which fields* flowed.

That's not "notes about your session". That's a graph: two roots and a join, with typed edges. The crystallizer (Filter → Reify → Resolve → Fingerprint → Generate) doesn't invent your play's structure — it **recovers** the structure your exploration already had:

| In the workspace | In the play |
|---|---|
| independent captures (`@1`, `@2`) | root steps — same layer, run in parallel |
| a capture that references others (`@3`) | a step with `depends_on` — ordering edges |
| the `@1{.path}` field references | `'@step{$.stdout.text \| fromjson \| .path}'` — value edges |
| the values you happened to use (`left-pad`) | typed parameters (`$package_name`) |

![Crystallization](assets/crystallize.svg)

This is why the guidance keeps repeating **"explore in the shape of the play you will crystallize"**. It isn't discipline for its own sake. The DAG is not something you design at export time — it's something you *lay down during exploration*, one reading per capture. Cram three API calls into one shell one-liner and the recorder sees one opaque blob: one step, no edges, nothing to parallelize, nothing to resume. Keep readings separate and the graph writes itself.

## Why the DAG is the foundation for everything downstream

Once work is a declared graph rather than a script, each hard runtime feature becomes a graph traversal:

- **Parallelism** — steps with no path between them run together; `[layer 2 — 4 parallel]` is free.
- **Resume** — a failed run knows precisely which nodes completed; `--resume` re-executes only the frontier. Completed steps *restore* their recorded outcomes — CAU immutability again, now at run time.
- **Per-source blame** — the stage ledger can say *which* source degraded, because each source is a node with its own outcome.
- **Inspection** — `play-dag` can draw any play's structure because the structure is data, not vibes.
- **Drift detection** — fingerprints pin the API identity each adapter step was compiled against, so "the API changed under this play" is detectable rather than mysterious.

And the run itself feeds back into the memory: each executing step's outcome is recorded just like exploration captures were — which is what the presentation layer reads, and why re-rendering a past run (`--resume … --output=json`) produces byte-identical facts in a different format.

## The full circle

```
  explore (three reaches)          crystallize                 share
  ┌──────────────────────┐   ┌──────────────────────┐   ┌───────────────────┐
  │ workspace canvas      │   │ Filter · Reify ·     │   │ hub URI, versioned │
  │ CAUs: @1 @2 @3 …      │ → │ Resolve · Fingerprint│ → │ inspectable card   │
  │ references = dataflow │   │ · Generate           │   │ anyone can run     │
  └──────────────────────┘   └──────────────────────┘   └───────────────────┘
              ↑                                                    │
              └────────── someone runs it, learns, explores ───────┘
```

The five gears the README names — **Adapt → Persist → Guide → Crystallize → Share** — are this circle. Plays are its center of gravity: everything upstream exists so a play can be born; everything downstream exists so a play can be trusted, found, and run.

---

**Next:** [9 · Reference →](09-reference.md)
