Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

The paved road (git work on a worktree, over the CLI)

The "paved road": the CLI routes an agent uses to do git work on its own worktree — commit the files it changed, sync onto the latest shared branch, stamp the branch ready to merge, hold and release a gate, hand a worktree over or take one back, reclaim a stranded one, and repair a broken dependency folder. Explains why the raw git commands are the wrong tool for each job.

What it is

When a session works in its own git worktree, the operations it wants are the ordinary ones — commit what I changed, catch up with the shared branch, mark my branch finished, throw the worktree away. Each of them has a raw git command, and each of those raw commands is the wrong tool, because Omniscio keeps a record of every worktree — who owns it, what it is for, whether it is still in use — and a raw command changes the repository without changing the record. The worktree then stops matching its own description: it reads as abandoned while it is still being worked in, or as live while it is gone.

The paved road is the set of routes that do those same operations and keep the record correct. Routing work through it is what makes a worktree's state trustworthy to everyone else.

Where to find it

This is a CLI-only surface — there is no button for it. The routes live on Omniscio's local control server at 127.0.0.1:19519, and they are the machines' side of the Work in Flight and Saved Work views.

  • GET /worktrees lists the worktrees with their branch, task and state, and is safe to read with any token. Start there to find the :id every other route takes.
  • Everything that changes something needs the full-trust token (~/.amc/cli-token from the Settings → CLI Control page). A session's own scoped token is deliberately refused on every mutation: a worktree operation can rewrite history or delete a branch, which is more than a spawned session should be able to do to the machine it is running on.

How it behaves

The routes fall into five jobs. Every body is strict: an unrecognised field is a 400 rather than a silently-ignored typo, which matters most on /sync, where a mistyped action would otherwise quietly default to starting a rebase. Five routes carry no body at all — remove, reclaim, release, gate-hold and gate-hold/release — and sending one is likewise a 400.

Reading what is really there. GET /worktrees/:id/status reports the branch, how far ahead and behind it is, whether it is dirty, the last commit, whether the ready-to-merge tag is set, and whether a rebase is half-finished. This is the honest read — use it instead of inferring state from the branch name.

Finishing your own work.

  • POST /worktrees/:id/commit stages the files you name, with the message you give it, and commits them. Naming them is the point: there is no "commit everything" and the paths are literal names rather than a wildcard, so one agent cannot sweep another's half-written work into its own commit.
  • POST /worktrees/:id/sync brings the branch up to date by replaying its commits on top of the shared branch. It rewrites this branch's history, so it takes an action: start (the default), continue or abort. A conflict stops the replay mid-way and reports it; you then either resolve by hand and continue, or abort to put the branch back exactly as it was. A half-done rebase is a state you are expected to finish, not one the route will guess its way out of.
  • POST /worktrees/:id/ready stamps the ready-to-merge tag, and requires a summary line that is recorded inside the tag. The tag names the exact commit it was taken at, so any later change to the branch invalidates it — that is the point: the tag is a claim about one specific tree, not a flag on the branch. It also accepts an optional evidence note and an optional human override; the override exists so a person can order a tag past a red gate by saying why, and a session using its own scoped token is refused that option — a check an agent can wave through is not a check.

Gates. POST /worktrees/:id/gate-hold marks a gate as running on this worktree and POST /worktrees/:id/gate-hold/release takes the mark off. Holding is what stops a cleanup sweep from reclaiming a worktree in the middle of a build; releasing it lets the sweep back in.

Passing a worktree between owners. POST /worktrees/:id/adopt takes ownership of the record, and POST /worktrees/:id/release hands it back. Neither touches git — they change only who the record says is responsible, which is what lets work be handed over without either side having to guess.

A recorded owner is not by itself a claim that somebody is still in that checkout: it names the session the worktree was issued to. So an owner that is still alive but has finished with this worktree — its work has landed and the checkout has sat untouched for six hours — no longer blocks a handover. adopt still asks for confirmTakeFromLiveOwner from a live owner; what changed (2026-10-02) is that it is no longer a flat refusal with no route out. And when a session is archived, its rows are handed back at that moment, so a successor is not refused not_owner while the finished session's name is still on the row.

Retiring one.

  • POST /worktrees/:id/remove retires your own worktree — the sanctioned replacement for the raw delete. It archives the branch tip before anything else, so the work is recoverable even on the path that also deletes the branch. A removal that is refused comes back as a 200 saying it did not remove (removed: false) with the reason, never as a success.
  • POST /worktrees/:id/reclaim retires a stranded worktree the caller does not own, and keeps the branch — it is the gentler of the two, for clearing up someone else's abandoned workspace without touching their commits. GET /worktrees/:id/reclaim-preview runs the same decision and writes nothing, so you can see what it would do first.
  • POST /worktrees/block parks a branch as blocked when there is no worktree involved at all.

Repairing one. POST /worktrees/:id/install-deps rebuilds a dependency folder that was left half-written, in place. It is the correct move when a worktree reports broken dependencies — deleting the folder by hand leaves the record disagreeing with the disk.

One route has a longer deadline than the rest. /ready is allowed to run well past the usual request timeout, because deciding whether a branch is landable involves a series of checks that cannot be hurried. A client that gives up on it early will see a failure where the operation actually completed.

For agents

Every route, with the token tier and body each one takes:

Method Path Body Token What it does
GET /worktrees/:id/status — any branch, ahead/behind, dirty, last commit, ready tag, rebase state
POST /worktrees/:id/commit { files[], message } full-trust stage those files and commit (explicit paths, never a pathspec; ≤500)
POST /worktrees/:id/sync { action } full-trust rebase onto the shared branch, rerere off (start | continue | abort, default start)
POST /worktrees/:id/ready { summary, evidence?, humanOverride? } full-trust stamp SHA-bound ready-to-merge (dispatchDeadlineMs = 15 min)
POST /worktrees/:id/gate-hold — full-trust stamp the gate-in-progress holding tag
POST /worktrees/:id/gate-hold/release — full-trust retract the holding tag
POST /worktrees/:id/adopt — full-trust take ownership of the ledger row (no git)
POST /worktrees/:id/release — full-trust hand the row back (no git)
POST /worktrees/block repo + branch facts full-trust park a branch blocked, no worktree needed
POST /worktrees/:id/reclaim — full-trust retire a stranded row the caller does not own, keeping the branch
GET /worktrees/:id/reclaim-preview — full-trust read-only dry run of reclaim
POST /worktrees/:id/remove — full-trust retire your own worktree (replaces git worktree remove)
POST /worktrees/:id/install-deps — full-trust repair a torn node_modules in place

Implementation: src/main/services/cli/cli-server-worktree-ops-routes.ts (lifecycle) and cli-server-worktree-ledger-routes.ts (/worktrees, /worktrees/:id, landed-proof, pin, install-deps, create, lease restore). Five routes — remove, reclaim, release, gate-hold and gate-hold/release — take no body and answer refusedUnhonouredBody (400) if one is sent. All mutations are registered { selfRateLimited: true } and bill the per-source paved-road bucket (429 rateLimitedWorktreeOp). /remove also carries the ledger's floor: a refusal returns 200 { removed: false } with the reason. Every body is .strict(), so a misspelled action on /sync is a 400 rather than a silent default (that schema carries z.enum([...]).default('start')). Invariants live in agent-git-paved-road-contract.md, worktree-ledger-contract.md and git-guardrails-contract.md rule 10.

Related

  • Session isolation — what a worktree is, why each session gets its own, and how the work inside one finds its way back.
  • Git guardrails — the protected-branch and destructive-operation blocks that sit above this surface.
  • Worktree cleanup — the bulk pass that retires worktrees whose work has already landed.
  • Orphan worktree archive — the background job that reclaims the disk folder of a worktree whose session has been gone a long time.
  • Where's My Work — the read-only screen that answers what happened to a branch's changes.
  • CLI Control — the local server these routes belong to, and where the full-trust token comes from.

Last verified 2026-10-02