Motivation
Two coding agents in one checkout write over each other, and a run that starts on a checkout someone else has edited builds on sand. A Git worktree per writer is the fix people already use by hand. The workspace contract does it inside the run: it records what the repository looked like, refuses to fork if that changed, gives one writer at a time the right to fork, and lands the work back when the step passes.Lifecycle
- Capture.
capture()records the repository’s revision and the state of its files, as an anchor. Pass Git pathspecs to limit it to the files a step may touch. - Verify.
verify(anchor)reads the repository again and reports any changed revision or path. A write you didn’t make shows up here, and you decide whether the run pauses. - Lease.
acquireLease()gives one writer the right to fork that anchor. The lease lives in a private Git ref, so a second writer is refused until the first releases it, and a delayed release can’t remove a later owner’s record. - Fork.
fork(anchor, child, token)creates a child branch and worktree beside the repository, at the anchor’s revision. A fork without a valid lease, or after the anchor changed, fails with a named kind instead of running on stale files. - Land back.
isolated(job)wraps any step in that cycle: it runs the step in its own worktree on a fork branch and, on pass, commits what the step left and merges the branch back, one merge at a time across the process. The worktree is removed and a cleanly merged branch is deleted, so parallel steps leave nothing behind.
Example
Capture, verify, lease and fork a fresh repository, then read the child:examples/workspace.ts (excerpt)
Example record
Limits
- One repository. The built-in provider captures one Git repository.
- Not a sandbox. Nothing stops a program outside the run from writing to the checkout. Verify reports that it happened; it doesn’t prevent it.
- You decide what a drift means. Verify reports changed paths. Pausing the run, and recording any branch or merge, is your program’s call. The graph executor doesn’t capture, verify or lease a workspace for you.
- No orphan cleanup. The provider can retry an incomplete fork, but it doesn’t remove abandoned child refs or worktrees.