Agent backend
Runs, provenance, checkpoints, workspaces, reviews, runners, previews, and the local JSONL API.
Synapse gives agent harnesses one local record of work: what ran, what changed, what was reviewed, where it ran, and how to recover it. The native Activity screen is the readable view. The CLI and JSONL API are the integration surfaces.
It does not replace a coding harness. A harness owns the model loop and tools; Synapse keeps the durable state around that work.
The run lifecycle
One task is one run. A run may have ordered steps, changed-file records, artifacts, checkpoints, reviews, comments, evaluations, a workspace, and previews.
- Create a run with the project identity, harness name, and structured input.
- Claim it from a runner. Renew the lease while work continues.
- Record steps and changes as they happen. Store large output as artifacts.
- Create checkpoints before risky edits. A checkpoint saves only explicit paths.
- Submit a review with checks, reasoning, and unresolved concerns. Comments may target the run, an event, step, artifact, change, or file and line.
- Mark the run succeeded, failed, waiting, or cancelled.
The event ledger is useful for observation, not authority. Structured run records are the source of truth.
Start with the CLI
Create a run by sending its input on stdin:
printf '%s\n' '{"task":"update the parser"}' | \
synapse backend run create --project github.com/acme/parser --harness mytool
Use the returned run id as $RUN. Record a changed file:
printf '%s\n' '{
"path":"src/parser.rs",
"operation":"modify",
"summary":"Handle an empty token stream"
}' | synapse backend changes record "$RUN"
Submit a review handoff:
printf '%s\n' '{
"reviewer":"reviewer",
"verdict":"changes",
"summary":"One regression case is missing",
"checks":[{"name":"cargo test","status":"passed"}],
"reasoning":"The empty input path is uncovered.",
"concerns":["Add an empty-input test"]
}' | synapse backend review submit "$RUN"
Read it back without knowing the storage schema:
synapse backend changes list "$RUN"
synapse backend review list "$RUN"
synapse backend comment list "$RUN"
Checkpoints
A checkpoint is deliberately explicit. Synapse does not sweep a repository or capture ignored files. The harness supplies relative paths beneath one root:
printf '%s\n' '{
"paths":["src/parser.rs","tests/parser.rs"],
"label":"before parser rewrite",
"state":{"phase":"editing"}
}' | synapse backend checkpoints create "$RUN" --root "$PWD"
Restore with the returned checkpoint id:
synapse backend checkpoints restore checkpoint-…
Restore replaces captured files, removes paths that were absent at capture time, and restores run and step state. Credential-shaped filenames, text that requires redaction, absolute paths, parent traversal, symlinks leaving the root, and more than 1,000 files are refused. One file may be at most 32 MiB and one checkpoint at most 128 MiB, so a malformed request cannot consume memory without a bound.
Isolated workspaces
Give a run a detached Git worktree:
synapse backend workspace create "$RUN" --root "$PWD"
The returned path is the worker's checkout. Accept its work explicitly:
synapse backend workspace merge "$RUN"
Merge checks the binary patch first, checkpoints every target path in the original checkout, applies the patch, records the file changes, and marks the workspace merged. It does not commit. Conflicting or credential-shaped changes are refused before the original checkout is modified. Patches are capped at 64 MiB and Git output is read through fixed ceilings. The detached worktree is removed after a successful merge; its checkpoint and provenance remain.
Fork and move a run
Forking keeps the parent task and input while isolating another approach:
synapse backend run fork "$RUN" --title "Try the smaller parser change"
Export carries the run, steps, changes, reviews, comments, evaluations, and attached artifacts. Worktree paths and checkpoint roots stay local:
synapse backend run export "$RUN" > run.json
synapse backend run import --project github.com/acme/parser < run.json
The import receives a new local id and keeps the source id in replayof.
Import structure, references, and size are validated before the new run is created;
a bundle accepts at most 16 MiB of artifact content.
Runners and previews
A runner says which machine can claim work and what it can do. No hosted control plane is required:
printf '%s\n' '{
"name":"Studio Mac",
"capabilities":["shell","git","preview"],
"local":true
}' | synapse backend runner put studio
synapse backend runner heartbeat studio busy
A runner may attach a development URL to a run:
printf '%s\n' '{
"id":"parser-preview",
"runnerid":"studio",
"url":"http://127.0.0.1:4000",
"status":"ready"
}' | synapse backend preview put "$RUN"
Synapse records the URL; it does not create a tunnel or publish a local port. A remote runner owns authentication and reachability. Preview URLs may not contain credentials or query parameters; authentication belongs outside the stored URL.
JSONL API
synapse backend api reads one request per line and writes one correlated response
per line. It opens no listener and exits at end of input.
{"version":1,"id":"runs","method":"runs.list","params":{"limit":20}}
Method families mirror the CLI: runs, steps, changes, reviews, comments,
artifacts, checkpoints, workspaces, runners, previews, events,
capabilities, triggers, routes, and evaluations.
Retention and trust
- Events retain 30 days and are capped at 50,000 rows.
- Runs retain 90 days and are capped at 10,000 rows. Active runs are not pruned.
- Completed run cleanup removes its managed detached worktree as well as its rows.
- Artifacts are content-addressed and verified when read.
- Individual artifacts are capped at 128 MiB; the local artifact store is capped at 10,000 records or 4 GiB, whichever comes first.
- Checkpoints, collaboration records, runners, previews, and evaluations have per-run or store-wide count limits.
- Secret-shaped text is refused or redacted before structured state is written.
- Filesystem restore rejects linked parent directories and artifact reads derive their path from the verified digest rather than trusting stored path text.
- Capabilities are default-deny and may be pinned to a content digest.
- A runner descriptor is not a trust grant. Project scopes still apply.