Toolpath at a glance

A story is made up of many paths, one step at a time.

A complete Toolpath document is small enough to read in one breath:

{
  "graph": { "id": "graph-step-001" },
  "paths": [
    {
      "path": { "id": "path-step-001", "head": "step-001" },
      "steps": [
        {
          "step": {
            "id": "step-001",
            "actor": "human:alex",
            "timestamp": "2026-01-29T10:00:00Z"
          },
          "change": {
            "src/main.rs": {
              "raw": "@@ -12,1 +12,1 @@\n-    println!(\"Hello world\");\n+    println!(\"Hello, world!\");"
            }
          }
        }
      ]
    }
  ]
}

That's the canonical fixture step-01-minimal.json — one author, one timestamp, one file changed, one diff. Every Toolpath document looks like this. The objects nest the same way. Bigger documents just hold more of them.

The shape

Every document is a Graph. A Graph holds Paths. A Path holds Steps. A Step is one change.

Layer Holds Represents
graph paths[] A collection of stories — a release, a project, a bundle
path steps[] One story — a PR, a coding session, a branch
step change{} A single change to one or more artifacts

Step and Path are inner types. They appear inside graph.paths and path.steps, but they're never the JSON root on their own — what used to be a bare Step or Path is now a single-path Graph. One root type, one parser path.

A step's change maps artifact URLs to perspectives — a unified diff under raw, a structural AST operation under structural, or both. The meta object is optional at every level: minimal documents need only step and change.

A real example

The lead example shows the shape. To see what Toolpath looks like when actual work has happened, open the exploration fixture in the visualizer. It's a single Path with seven steps and the four DAG features that recur everywhere:

→ Open it in the visualizer (it's the default example) and the structure clicks immediately.

File extensions

Extension Shape Use it when
.path.json Graph (canonical) Sealed documents — PRs, releases, archived sessions
.path.jsonl Graph (streaming) Live capture — one Path appended line-by-line as work happens

A .path.jsonl stream encodes exactly one inline Path and seals to a single-path Graph at the file boundary. Multi-path graphs and $ref-only entries can't be represented in JSONL — those require canonical .path.json.

Where to next