mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
112 lines
7.5 KiB
Markdown
112 lines
7.5 KiB
Markdown
# Workspace Structure
|
|
|
|
## Multi-Agent Isolation
|
|
|
|
Each agent gets their own git clone:
|
|
|
|
```
|
|
{workspaces_root}/
|
|
└── {project-slug}/
|
|
└── {team}/
|
|
└── {agent-slug}/
|
|
└── [git repo files]
|
|
```
|
|
|
|
## Example
|
|
|
|
```
|
|
/data/workspaces/
|
|
└── roboco/
|
|
├── backend/
|
|
│ ├── be-dev-1/ # be-dev-1's workspace
|
|
│ ├── be-dev-2/ # be-dev-2's workspace
|
|
│ ├── be-qa/ # be-qa's workspace
|
|
│ ├── be-pm/ # be-pm's workspace
|
|
│ └── be-doc/ # be-doc's workspace
|
|
├── frontend/
|
|
│ ├── fe-dev-1/
|
|
│ └── ...
|
|
└── ux_ui/
|
|
└── ...
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```bash
|
|
# Environment variables
|
|
ROBOCO_WORKSPACES_ROOT=/data/workspaces
|
|
ROBOCO_WORKSPACE_AUTO_CLONE=true
|
|
ROBOCO_WORKSPACE_CLONE_TIMEOUT=300
|
|
```
|
|
|
|
## Features
|
|
|
|
| Feature | Description |
|
|
|---------|-------------|
|
|
| Auto-clone | Workspaces created on first access |
|
|
| Isolation | No file locking conflicts |
|
|
| Branch independence | Agents on different branches |
|
|
| Project-scoped | Organized by project slug |
|
|
|
|
## Benefits
|
|
|
|
1. **Parallel Development**: Multiple agents on same project
|
|
2. **No Conflicts**: Each has own working tree
|
|
3. **Branch Flexibility**: Different branches simultaneously
|
|
4. **Clean State**: Fresh clone if needed
|
|
|
|
## Per-Task Worktrees (F123)
|
|
|
|
Your agent clone is **shared across all your tasks**, but each **claimed task** gets its own linked git worktree — a separate working directory on the same underlying clone — so two of your in-progress tasks never clobber each other on one checkout (this is what lets a coordinator PM hold several roots at once, and what stops a fresh claim from `reset --hard`-ing uncommitted work on your still-active first task).
|
|
|
|
```
|
|
{workspaces_root}/{project}/{team}/{agent}/ # the clone root (shared)
|
|
├── .git/ # the real object store (shared)
|
|
├── .venv/ # the per-project venv (shared, agent-owned)
|
|
├── .uv-python/ # uv's managed CPython (shared, gitignored)
|
|
└── .worktrees/
|
|
└── {task-short}/ # ONE per claimed task — your cwd for that task
|
|
├── .venv -> ../../.venv # symlink to the clone-root venv
|
|
└── [your task's checked-out branch]
|
|
```
|
|
|
|
- **Claim** (`i_will_work_on` / `claim_review` / `claim_doc_task`) adds a worktree at `.worktrees/{task-id-first-8}/` and checks out the task's branch there. The clone root's HEAD is **never moved** by a claim.
|
|
- **Your container is started with `-w` pointing at the worktree** for your current task, so `commit`, edits, and `uv run` all resolve there automatically. Spawn resolves the worktree from your `current_task_id` on every spawn (never cached), so a resume/respawn re-attaches a pruned worktree before launch. Every spawn also RE-SYNCS an already-present worktree against origin (role-aware): if you're a developer/documenter, your own dirty uncommitted edits are never discarded to do it — a behind-or-equal worktree fast-forwards, a strictly-ahead one (your own unpushed commits) is left exactly alone; if you're QA/PR-gate/PM reviewing someone else's branch, a diverged worktree hard-resets to origin, since your local history there can only ever be a stale prior-round checkout. This closes the "reviewer keeps re-examining its own frozen round-1 checkout across a multi-round bounce" class — you're never respawned onto commits older than what's actually on the branch.
|
|
- **The clone-root `.venv` is shared** — each worktree's `.venv` is a symlink to `../../.venv`, so `uv run` from a worktree resolves the clone-root venv. No per-worktree re-sync.
|
|
- **Git ops split by kind**: checkout/HEAD-moving ops (`create_branch`, `commit`, `rebase`, `checkout`) target the worktree; branch-by-name ops (`push`, `pull`, `fetch`, `pr_merge`, `diff`) run from the clone root. You never do either by hand — the verbs resolve the worktree for you.
|
|
- **One active WorkSession per task** is enforced both in the service layer and by a DB unique index — a re-claim (pool release, reaper unclaim, escalation redirect) supersedes any prior agent's stale session for that task.
|
|
- **Claim rollback** (a mid-claim failure) `worktree remove --force`s the worktree so a retry doesn't collide with a stale one.
|
|
- **Terminal completion** (`complete` / `ceo_approve`) and **cancellation** remove the assignee's worktree AND force-delete the now-spent local branch ref in the clone, so finished/cancelled tasks don't leak either on disk. A `needs_revision` bounce keeps both — you need the branch back. The stale-claim reaper does **not** remove the worktree or branch; it routes the task to `pending` for a re-claim that reuses them. A PM/CEO can also run a backlog stale-branch sweep from the panel's Git page for older completed/cancelled tasks whose ref survived from before this reaping existed.
|
|
|
|
You do not manage any of this. The verbs do. The only thing you must know: **your cwd is the worktree for your current task, not the clone root** — so relative paths and `uv run` resolve against your task's checkout.
|
|
|
|
## The `/app/.venv` is sacred — never retarget onto it
|
|
|
|
Two venv classes exist in the container:
|
|
|
|
- **Workspace venvs** — per-project, agent-owned, under `/data/workspaces/.../{agent}/.venv`. These are yours.
|
|
- **`/app/.venv`** — the image-baked MCP-gateway venv. The MCP servers (`roboco-flow`, `roboco-do`, the git-readonly server) import from here. **It is sacred. If it breaks, every tool you have stops spawning.**
|
|
|
|
A past live incident: an agent hit a permission error on its workspace venv, followed uv's hint to run `uv run --active`, and that retargeted onto `VIRTUAL_ENV=/app/.venv` (baked globally) — uv rebuilt `/app/.venv` from a drifted lock and deleted its `bin/`, bricking every MCP server spawn fleet-wide.
|
|
|
|
The bash-guard hook now **blocks** `uv run --active` and any `uv run` / `uvx` against `/app` (`--project /app`, `--directory /app`, `UV_PROJECT_ENVIRONMENT=/app`, `cd /app && uv ...`). If you ever feel tempted to use `--active` or point uv at `/app`, **don't** — call `i_am_blocked(reason='workspace venv broken')` instead and let the environment be rebuilt. Bare `uv run` (cwd-relative, your workspace venv) is always fine and always what you want.
|
|
|
|
## No Workspace Tools — It's Automatic
|
|
|
|
There are **no** agent-facing workspace tools. Workspaces and per-task worktrees are created for you by the orchestrator (`WorkspaceService`) before your container starts. You never `ensure`, `clone`, `checkout`, or `worktree add` by hand — your repo is already on disk, the worktree for your current task is already linked and `-w`'d as your cwd, and the gateway verbs (`i_will_work_on`, `claim_review`, ...) check out the right branch in it.
|
|
|
|
## Workspace Resolution
|
|
|
|
Path resolved automatically: `{workspaces_root}/{project}/{team}/{agent}/`
|
|
|
|
If `auto_clone=True` and workspace doesn't exist, it's created on first access.
|
|
|
|
## Authentication
|
|
|
|
HTTPS repositories require a git token configured on the project — the field is historically named for GitHub PATs but works unchanged for a project registered against Gitea or GitLab (`projects.git_provider`):
|
|
|
|
- **Token configured**: Auto-clone works, git operations succeed
|
|
- **Token missing**: Error "Project requires a git token for HTTPS repositories"
|
|
|
|
**If you see this error**: Contact your PM. The project's git token is configured by a human in the control panel (project settings) — it is not an agent tool. The token is encrypted at rest and never exposed to your container; the orchestrator injects it into git operations for you.
|