Workspaces
Workspaces
A workspace holds a team's work and the handles that carry it. One person owns it. This page shows how to set one up, who can do what in it, and how to change its settings.
A handle is a name that carries work. Each handle belongs to a person or to an agent. A carrier is the handle that holds a piece of work now.
Before you start
Sign in first, as Sign in shows. This page builds a workspace from the start. It is called billing, its owner's handle is dana, and it gets the agent handles build-agent and review-agent and a person handle, sam. If you made billing in Your first relay, that name is taken. Use another workspace name here, or read along.
Create a workspace
Create the workspace and name your own handle:
handsoff workspace create billing --owner-handle dana
Workspace billing created and selected (21)
You own the workspace now, and dana is your person handle. If you leave out --owner-handle, your handle is called owner. The number in brackets is the workspace's id. Yours will differ.
The tool selects the new workspace for you, so later commands use it. To see your workspaces and choose another one:
handsoff workspace list
…
billing (21)
handsoff workspace use billing
Using workspace billing (21)
workspace list shows every workspace where you hold a handle. To use a workspace for one command only, add --workspace <name> to that command.
Names are shared
Workspace names are shared by everyone on the service. Two teams cannot both have a workspace called billing. If the name is taken, the tool prints these two lines and creates nothing:
handsoff workspace create billing --owner-handle dana
This request cannot be used; check its fields and send it again.
invalid: the name, reference or related record is not usable; choose a new name or check the requested ids; fix: check the documented request fields and send it again
The first line is for you. The second line is for the agent that ran the command. Pick another name, such as your team's name, and run the command again.
Add handles
Only the owner adds handles. A handle name has two to forty characters: lowercase letters, digits, dots, underscores or dashes. Each name is used once in a workspace.
A handle you use yourself
Add --mine to bind the handle to your own sign-in. Do this for the agents that run on your machine:
handsoff handle add build-agent --kind agent --mine
Added agent handle build-agent
handsoff handle add review-agent --kind agent --mine
Added agent handle review-agent
You act as one of these handles with --as, for example --as build-agent. An agent can set HANDSOFF_HANDLE instead. Tell your agents shows how.
A handle for someone else
Leave out --mine. The tool prints a claim code once:
handsoff handle add sam --kind person
Added person handle sam
Claim code: e0d076dd6f6a0ccaac9104aa01ee823a
Give this code to whoever will use sam. It works once and expires at 2026-10-06T04:11:25.528757+00:00 (24 hours). It is not shown again.
Send the code to that person in private. The service stores only a one-way fingerprint of it, so nobody can show the code again.
The person signs in on their own machine and runs handsoff handle claim. The tool waits for one line and prints no prompt. They paste the code and press Enter:
handsoff handle claim
Claimed handle sam in workspace billing (21)
Reading the code this way keeps it out of the shell's history. The handle now belongs to that person's sign-in. If their machine has no workspace selected, the claim selects this one.
A code works once. A used, mistyped or old code gets this answer:
handsoff handle claim
This claim code is not valid: it may be mistyped, already used, or older than 24 hours. Ask the workspace owner for a new handle.
invalid: claim code invalid; fix: ask the workspace owner for a new handle
The owner cannot print a code again. To give the person a new code, disable the handle and add one with a new name.
A name the tool refuses
A name with a capital letter or a space is refused:
handsoff handle add Sam --kind person
This request cannot be used; check its fields and send it again.
invalid: handle names need two to forty lowercase letters, digits, dots, underscores or dashes; fix: check the documented request fields and send it again
List and disable handles
handle list shows every handle and its kind:
handsoff handle list
dana: person
build-agent: agent
review-agent: agent
sam: person
To stop a handle from acting, disable it:
handsoff handle disable sam
Disabled handle sam
handsoff handle list
dana: person
build-agent: agent
review-agent: agent
sam: person (disabled)
A disabled handle cannot act or read. Its past work stays in the history under its name. Handsoff never deletes a handle, and a workspace never uses the same name twice. Adding sam again gets the "This request cannot be used" lines shown above.
The owner's own person handle stays enabled, so a workspace can never lock its owner out:
handsoff handle disable dana
The owner's person handle must stay enabled; choose another handle.
not_allowed: owner handle cannot be disabled; fix: choose a member handle
Who can do what
Every enabled handle in a workspace can:
- Read all the work in the workspace and its history.
- Open, save, offer, catch, renew, note, block and end work.
Only the owner can:
- Add and disable handles.
- Change the workspace settings.
- Take back an offer that another handle made.
- Unblock or close work that the owner does not carry.
That is the whole permission model. There are no other roles.
Owner rights go with your sign-in
The owner is your sign-in, not one handle. A handle you added with --mine acts under your sign-in, so it has your owner rights too. An agent that acts as build-agent here can add handles and change settings. Give an agent its own sign-in and a claimed handle if it must not do that.
A workspace gives no access to anything a baton points to. A baton can name a tracker, a document or a secret store. Handsoff never opens them, and a handle needs its own access to reach them.
Workspace settings
Each workspace has three settings. Anyone with a handle there can read them:
handsoff workspace settings
Workspace billing (21)
default lease 30m (1800 seconds)
default offer deadline 1d (86400 seconds)
stall threshold 1h (3600 seconds)
These are the values a new workspace starts with:
- Default lease: how long a carrier holds work before the hold runs out. A renewal starts the lease again. Leases and carriers explains leases.
- Default offer deadline: how long an offer waits for someone to catch it.
- Stall threshold: how long held work can go without a saved baton before lists show it as stalled.
To read another workspace's settings, name it: handsoff workspace settings billing.
The owner changes a setting with its flag. Give a number of seconds, or a number with s, m, h or d:
handsoff workspace settings --default-lease 1h --offer-deadline 2d
Workspace billing (21)
default lease 1h (3600 seconds)
default offer deadline 2d (172800 seconds)
stall threshold 1h (3600 seconds)
The tool prints the new values. Work that is already held keeps the lease length it started with.
The limits
| Flag | Lowest | Highest |
|---|---|---|
--default-lease | 1m (60 seconds) | 12h (43200 seconds) |
--offer-deadline | 1m (60 seconds) | 7d (604800 seconds) |
--stall-after | 1s (1 second) | 2147483647 seconds |
A value outside these limits changes nothing. The tool says what the limit is:
handsoff workspace settings --default-lease 59s
The default lease must be from 1 minute to 12 hours; choose a value in that range.
invalid: the requested operation needs correction; fix: use --default-lease from 1m to 12h
handsoff workspace settings --offer-deadline 8d
The default offer deadline must be from 1 minute to 7 days; choose a value in that range.
invalid: the requested operation needs correction; fix: use --offer-deadline from 1m to 7d
handsoff workspace settings --stall-after 2147483648
This request cannot be used; check its fields and send it again.
invalid: stall_seconds must be a positive integer; fix: check the documented request fields and send it again
A zero or a word that is not a duration gets this:
handsoff workspace settings --default-lease 0
That duration is not valid; use seconds or s, m, h, d.
invalid: the requested operation needs correction; fix: use a positive duration such as 30m
A carrier can ask for a different lease on one piece of work with --lease on open or continue, and a different deadline on one offer with --deadline. The same limits apply: from 60 seconds to 12 hours for a lease, and from 60 seconds to 7 days for an offer.