# Workspace and collaboration administration

Use the client CLI to administer collaboration state from any computer: list
workspace registrations, retire an old registration, or release abandoned locks.
Use the server CLI on the storage host for doctor, backup/restore, repair, and
migration. Those maintenance commands need exclusive access to the data root;
remote workspace and lock administration runs while the server is serving.

A working copy has local `.scribe/_state/` state and, except for anonymous public
working copies, a server registration. The registration is identified by an
immutable workspace ID. Local files, opened work, recovery copies, and sync
journals stay on the computer; the server does not know whether an editor is
currently open there.

## Example: replacing a game developer's computer

Suppose your old computer had a `Game` workspace and a separate `Engine`
workspace used by a project mount. Both registrations remain on the server when
you stop using that computer. On the new computer, connect to the same storage
endpoint or gateway and, with auth enabled, log in as the same user. No local
checkout is needed for these commands:

```sh
scribe workspace list --all-repos
scribe workspace remove GAME_WORKSPACE_ID --repo Game
scribe workspace remove ENGINE_WORKSPACE_ID --repo Engine
```

Replace the placeholders with the full IDs from the inventory. Each removal
affects one registration in one repository; removing the Game registration does
not also remove Engine's registration or alter any project mount pins. If either
workspace holds locks, follow the explicit unlock procedure below first.

The new computer gets new workspace IDs when you create its working copies.
Listing old registrations does not download their unsubmitted files: those files
still belong to the old computer and must be copied separately if needed.

## Inventory from another computer

```sh
scribe workspace list --repo Game
scribe workspace list --all-repos
scribe workspace list --repo Game --everyone
scribe workspace list --all-repos --everyone
```

Without `--repo` or `--all-repos`, listing selects the current workspace's
repository; outside a workspace it selects all accessible repositories. Use the
global `--server URL` to select another storage endpoint or gateway.
`--all-repos` selects repositories; `--everyone` selects owners within those
repositories. Neither flag grants permission. For example, an administrator can
use `scribe --server tls://gateway.example:7447 workspace list --all-repos --everyone`
after configuring TLS trust and credentials for that endpoint.

Authenticated listing defaults to registrations owned by the current principal.
`--everyone` requires Maintainer permission in each selected repository; a
namespace administrator has that permission throughout the namespace. A denied
repository fails the command rather than silently presenting an incomplete admin
inventory. Anonymous clients cannot inspect registrations, even in public repos.
Without auth there is no verified owner, so both forms list all registrations.

Output includes the full workspace ID, repository, immutable owner ID (or
`unowned`), label, tags, creation time, and whether locks are held. JSON
additionally includes the branch ID. A label is descriptive, not proof of
identity or a presence indicator. Tags (`name` or `name=value`, at most 16)
are set when the workspace is registered and never change; they say what made
it — a runner registers `runner` and `runner-id=<id>` — and `--tag` narrows
the listing to them, so retiring a decommissioned runner's workspaces is one
list and a loop. Creation time is not a last-active timestamp. Re-registering
during a branch or view change preserves the original machine label, tags and
creation time. Registrations do not expire merely because a computer is offline; select
the registrations to retire explicitly.

The storage API returns at most 128 registrations per page, using an exclusive
workspace-ID cursor. Own-workspace queries seek an owner index; they do not scan
other owners. The CLI follows pages and bounds accumulated inventory to one
million entries. Server-wide inventory follows accessible repository discovery
through the same endpoint, including repositories routed by a gateway. This is a
live inventory, not a cross-repository snapshot.

## Permissions in each server setup

| Setup | Default inventory | Other owners and forced unlock |
| --- | --- | --- |
| Direct storage, no auth | All registrations in the selected repositories | Any connected client |
| Gateway to storage without auth | All registrations in the selected routed repositories | Any connected client |
| Direct storage with auth | The signed-in principal's registrations in readable repositories | Maintainer in each affected repository |
| Gateway to storage with auth | The same owner and repository filtering as direct access | The same Maintainer check at storage |

A namespace administrator inherits Maintainer authority in that namespace.
An auth-administrator credential alone does not grant storage access. A gateway
forwards the caller's access certificate and acts for that user only through
its delegate grant; its own inventory credential does not authorize client
operations. Anonymous public access on an authenticated server cannot
list or remove workspace registrations. That is different from a server with
auth disabled, where connected clients are trusted.

An owner with repository read access may remove their own registration.
Removing another owner's registration or using `--everyone` requires Maintainer.
Force-unlock requires Maintainer even if the lost workspace belonged to you;
ownership alone does not authorize force-unlock from a second computer.

With auth, one user can register at most 64 new workspaces per hour on a
storage server; beyond that, `workspace create` and `workspace register` fail
with `too many new workspaces this hour; reuse or remove existing workspaces
and retry later` (`limit_exceeded`). Re-registering a workspace you already own
is not counted.

## Retire an old registration

Copy its full ID from the inventory:

```sh
scribe workspace remove WORKSPACE_ID --repo Game
```

With auth, the owner needs repository read access; removing another owner's
registration requires Maintainer permission. Namespace administrators inherit
that authority. Without auth, any connected client can remove a registration.

Removal permanently retires the identity. It deletes the active registration,
returns its active-workspace quota slot, and retains a small retirement record.
The old identity cannot register again, acquire locks, or publish new changes.
Accepted history and previously recorded submit outcomes remain available.
Local files and `.scribe/_state/recovery` are never touched. To work again from the old
computer, create a fresh workspace in a separate directory and copy the needed
local work into it. Preserve the old working copy and recovery files until that
work is accounted for. Retirement has no undo command.

Held locks block removal. Inspect them and explicitly release the intended paths:

```sh
scribe lock list --repo Game
scribe lock release --repo Game --force Source/example.cpp
scribe workspace remove WORKSPACE_ID --repo Game
```

Forced unlock requires Maintainer with auth and works without a local checkout.
Choose only paths whose lock holder matches the workspace being retired. With
`--repo`, paths are exact repository-relative paths, independent of the current
directory. The CLI names the observed lock generation so a race cannot release
a newer lock. There is no automatic unlock or cascading removal.
Ordinary owners can unlock from their original workspace; being an owner does
not grant permission to force-unlock from another working copy.

### Interrupted removal

The CLI durably saves each removal intent under the endpoint's per-user
`workspace-removals` configuration directory before transmission. If a connection
fails, repeat the same command: it first resolves the recorded outcome, then
retransmits only when no outcome exists. Reusing an operation ID with changed
intent is refused. With auth, an operation ID recorded by another user answers
exactly like an unknown one, so outcomes are never disclosed across accounts. A recorded lock rejection remains that operation's result;
a later invocation after releasing locks creates a new intent. Removal is
serialized with publication and checked transactionally against lock acquisition.
An in-flight submit either finishes before retirement or is rejected; its prior
accepted result is never revoked.
If the repository was restored and the old intent cannot be resolved, the CLI
archives that intent and asks you to review the target before repeating removal.

## Administration boundary

| State or task | Tool / location | Authority |
|---|---|---|
| Workspace registrations | Client `workspace list/remove`, direct or gateway | Owner; Maintainer for other owners |
| Locks | Client `lock list`, `lock release --force`, direct or gateway | Reader to inspect; Maintainer to force-unlock |
| Sessions, users, credentials, grants | Auth CLI revocation and administration | Auth administrator; ordinary logout revokes its own session |
| Unfinished branch snapshots | Server-local `staging-branches --abandon` | Data-root access and exclusive root lock |
| Doctor, verification, backup, restore, repair, migration | Server-local CLI | Data-root access and exclusive root lock |
| Interrupted submit / merge / move / project publication | Existing outcome lookup and resume/abort workflow | Operation owner; accepted history remains immutable |
| Upload staging leftovers | Existing object-store startup recovery | Server under the exclusive root lock |

The repository roles in this table apply when auth is enabled. Without auth,
connected clients have the remote workspace and lock authority described above.
Server-local maintenance requires filesystem access and the root lock in every
setup; stop the storage server before running it. Logging in as Maintainer does
not give a client remote backup, restore, or repair access.

Reuse repository Maintainer and namespace-administrator grants for remote
collaboration administration. An auth administrator credential does not
implicitly grant storage access, and a storage server's credential cannot
administer users. There is no master credential or remote
filesystem-maintenance endpoint. Without auth, remote collaboration
administration is trusted-access: anyone who can connect has access. A gateway
forwards the caller's access certificate and leaves repository authorization to
storage; its own credential never grants client admin privileges.

Removing operation records is not a cleanup mechanism: they prevent retries from
executing a mutation twice. Active branches and accepted history have no force
removal. Server-local maintenance remains separate from remote administration.
See [operations](/docs/operations.md), [authentication](/docs/auth.md), and
[project recovery](/docs/project-workflows.md#resume-or-abort).
