mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
docs(rag): rewrite the KB docs to the real gateway verb surface
The RAG knowledge base (indexed and queried by agents at runtime) described entire fictional MCP tool surfaces — roboco_task_*, roboco_journal_*, roboco_message_send, roboco_notify_send, roboco_agent_*, roboco_session_*, roboco_workspace_*, roboco_project_* — that don't exist, so agents searching the KB were handed invented tool names. Rewrite every affected doc (tools, roles, workflows, troubleshooting, and the stale architecture snippets) to the real surface: the gateway intent verbs (give_me_work, i_will_work_on, open_pr, i_am_done, claim_review, pass, fail, claim_doc_task, i_documented, triage, delegate, i_will_plan, unblock, complete, escalate_up, escalate_to_ceo, ...) and content tools (commit, note(scope=...), say, dm, evidence, notify*, open_session, channels). Also reconcile the access-control docs to code: CEO can cancel (Board/Auditor cannot); the management-channel membership and the Auditor's silent-but-present status now match communications.py.
This commit is contained in:
+37
-61
@@ -1,82 +1,58 @@
|
||||
# A2A (Agent-to-Agent) Tools
|
||||
|
||||
## Overview
|
||||
A2A is direct peer-to-peer messaging between agents. There is **no**
|
||||
`roboco_agent_*` or `roboco_a2a_*` tool — A2A is the `dm` content tool on
|
||||
the `roboco-do` MCP server, with `channels()` for discovery and the
|
||||
notify inbox for receiving.
|
||||
|
||||
A2A enables direct peer-to-peer communication between agents about existing tasks.
|
||||
|
||||
**Key points:**
|
||||
- Direct HTTP when both agents online (no notification)
|
||||
- Fallback to notification only when target offline
|
||||
- All requests MUST reference an existing `task_id`
|
||||
|
||||
## Tools
|
||||
|
||||
### roboco_agent_discover
|
||||
|
||||
Find agents by role, team, or skill.
|
||||
## Send a direct message — `dm`
|
||||
|
||||
```python
|
||||
roboco_agent_discover(
|
||||
role="developer", # Optional: developer, qa, documenter, cell_pm, etc.
|
||||
team="backend", # Optional: backend, frontend, ux_ui
|
||||
skill="code_review" # Optional: specific capability
|
||||
dm(
|
||||
recipient="be-qa", # target agent slug
|
||||
text="Please review my changes",
|
||||
task_id="abc123...", # auto-filled from your active task if omitted
|
||||
skill=None, # optional skill slug to scope the conversation
|
||||
)
|
||||
```
|
||||
|
||||
### roboco_agent_request
|
||||
- Auto-creates the conversation; auto-resolves the skill if needed.
|
||||
- **Same-cell only.** Cross-cell DM is denied by policy — route through
|
||||
your Cell PM via `escalate_up(task_id, reason)`.
|
||||
- The recipient sees it in their notify inbox when offline.
|
||||
|
||||
Send A2A message to another agent.
|
||||
## Discover who/where to message — `channels`
|
||||
|
||||
There is no agent-directory tool. Use `channels()` to see the channels
|
||||
you can read/write, and post to a channel when the audience is the whole
|
||||
cell rather than one peer:
|
||||
|
||||
```python
|
||||
roboco_agent_request(
|
||||
target_agent="be-qa",
|
||||
skill="code_review",
|
||||
message="Please review my changes",
|
||||
task_id="abc123...", # REQUIRED
|
||||
options={"urgent": False} # Optional: priority queue
|
||||
)
|
||||
channels() # -> {"writable": [...], "readable": [...]}
|
||||
say(channel="backend-cell", text="Anyone hit Y before? Starting task X.")
|
||||
```
|
||||
|
||||
**Returns:** `{status, delivery, message_id}` where `delivery` is `"direct"` or `"notification"`.
|
||||
## Receive incoming messages
|
||||
|
||||
### roboco_a2a_check
|
||||
|
||||
Poll your inbox for incoming A2A messages.
|
||||
Incoming A2A and @mentions land in your notify inbox. When `i_am_idle()`
|
||||
soft-blocks on unread items, drain the inbox:
|
||||
|
||||
```python
|
||||
roboco_a2a_check()
|
||||
notify_list(unread_only=True) # list pending items
|
||||
notify_get(notification_id) # read one (marks it read)
|
||||
notify_ack(notification_id) # acknowledge after handling
|
||||
```
|
||||
|
||||
**Returns:** `{messages: [...], count: N}` - messages from other agents.
|
||||
## When to use A2A
|
||||
|
||||
**Note:** A hook automatically notifies you of pending messages after tool calls.
|
||||
- A quick question, sanity check, or hand-off about a task you own
|
||||
- Requesting code review or clarification from a same-cell peer
|
||||
|
||||
## Common Use Cases
|
||||
## When NOT to use A2A
|
||||
|
||||
| Need | Action |
|
||||
|------|--------|
|
||||
| Code review | `roboco_agent_request("be-qa", "code_review", "...", task_id)` |
|
||||
| Clarification | `roboco_agent_request("be-pm", "clarification", "...", task_id)` |
|
||||
| Find reviewer | `roboco_agent_discover(skill="code_review")` |
|
||||
| Urgent help | `roboco_agent_request(..., options={"urgent": True})` |
|
||||
|
||||
## When to Use A2A
|
||||
|
||||
- Communication about an existing task you're working on
|
||||
- Requesting code review, clarification, or help
|
||||
- Notifying another agent about task progress
|
||||
- Urgent questions needing immediate attention
|
||||
|
||||
## When NOT to Use A2A
|
||||
|
||||
- Creating new work → Only PMs create tasks via `roboco_task_create`
|
||||
- Task assignments → PM assigns via `roboco_task_assign`
|
||||
- Escalations → Use `roboco_task_escalate`
|
||||
- Formal notifications → Use `roboco_notify_send` (PM only)
|
||||
|
||||
## Task Creation Rules
|
||||
|
||||
Only Cell PMs and Main PM can create tasks (subtasks).
|
||||
If an agent receives an A2A request that requires new work:
|
||||
1. Escalate to PM: `roboco_task_escalate(task_id, "Needs subtask for...")`
|
||||
2. PM decides whether to create a subtask
|
||||
| Need | Do this instead |
|
||||
|------|-----------------|
|
||||
| Cross-cell question | `escalate_up(task_id, reason)` — DM is same-cell only |
|
||||
| New work / subtask | Only PMs create work, via `delegate(...)`; escalate to your PM |
|
||||
| Formal, ack-required signal | PM/Board `notify(target, text, ...)` |
|
||||
| Cell-wide broadcast | `say(channel=..., text=...)` |
|
||||
|
||||
@@ -1,92 +1,121 @@
|
||||
# Journal Tools
|
||||
|
||||
## Creating Entries
|
||||
There is **no** `roboco_journal_*` tool. Journaling is a single content
|
||||
tool on the `roboco-do` MCP server: `note`. The `scope` argument selects
|
||||
the entry kind; structured fields are filled per scope.
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_journal_entry` | General entry |
|
||||
| `roboco_journal_decision` | Decision log |
|
||||
| `roboco_journal_learning` | Learning capture |
|
||||
| `roboco_journal_struggle` | Problem/solution |
|
||||
| `roboco_journal_reflect` | Task reflection |
|
||||
```python
|
||||
note(
|
||||
text: str, # always: one-paragraph summary
|
||||
scope: str = "note", # note | decision | reflect | learning | struggle
|
||||
task_id: str | None = None, # auto-filled from your active task if omitted
|
||||
title: str | None = None,
|
||||
# decision-scope fields:
|
||||
context: str = "",
|
||||
options=None, # list of {name, pros, cons} (a single dict is ok)
|
||||
chosen: str = "",
|
||||
rationale: str = "",
|
||||
consequences=None, # list of strings (a single string is ok)
|
||||
# reflect-scope fields:
|
||||
what_done: str = "",
|
||||
what_learned: str = "",
|
||||
what_struggled: str = "",
|
||||
next_steps=None, # list of strings (a single string is ok)
|
||||
)
|
||||
```
|
||||
|
||||
`text` is always required. Missing narrative fields default to a visible
|
||||
placeholder rather than being rejected — the note is always recorded.
|
||||
|
||||
## Scopes
|
||||
|
||||
| Scope | Use For | Structured fields |
|
||||
|-------|---------|-------------------|
|
||||
| `note` | General entry | (just `text`) |
|
||||
| `decision` | Decision log | `context`, `options`, `chosen`, `rationale`, `consequences` |
|
||||
| `reflect` | Task reflection | `what_done`, `what_learned`, `what_struggled`, `next_steps` |
|
||||
| `learning` | Learning capture | (just `text`) |
|
||||
| `struggle` | Problem / blocker | (just `text`) |
|
||||
|
||||
## General Entry
|
||||
|
||||
```python
|
||||
roboco_journal_entry({
|
||||
type: "learning",
|
||||
title: "Redis SCAN vs KEYS",
|
||||
content: "SCAN is better for large datasets",
|
||||
task_id: task_id,
|
||||
tags: ["redis", "performance"]
|
||||
})
|
||||
note(
|
||||
text="SCAN is better than KEYS for large datasets",
|
||||
scope="learning",
|
||||
title="Redis SCAN vs KEYS",
|
||||
task_id=task_id,
|
||||
)
|
||||
```
|
||||
|
||||
Entry types: `task_reflection`, `decision_log`, `learning`, `struggle`, `general`
|
||||
|
||||
## Decision Log
|
||||
|
||||
```python
|
||||
roboco_journal_decision({
|
||||
title: "Session storage choice",
|
||||
context: "Need fast session lookups",
|
||||
options: ["PostgreSQL", "Redis"],
|
||||
chosen: "Redis",
|
||||
rationale: "Sub-ms reads, ephemeral data"
|
||||
})
|
||||
note(
|
||||
text="Chose Redis for session storage over PostgreSQL.",
|
||||
scope="decision",
|
||||
title="Session storage choice",
|
||||
context="Need fast session lookups",
|
||||
options=[
|
||||
{"name": "PostgreSQL", "pros": "durable", "cons": "slower reads"},
|
||||
{"name": "Redis", "pros": "sub-ms reads", "cons": "ephemeral"},
|
||||
],
|
||||
chosen="Redis",
|
||||
rationale="Sub-ms reads, ephemeral data",
|
||||
consequences=["Session loss on Redis restart is acceptable"],
|
||||
)
|
||||
```
|
||||
|
||||
## Learning
|
||||
|
||||
```python
|
||||
roboco_journal_learning({
|
||||
content: "asyncio.gather for parallel calls",
|
||||
how_applied: "Reduced latency 50%",
|
||||
category: "performance",
|
||||
tags: ["async"]
|
||||
})
|
||||
note(
|
||||
text="asyncio.gather for parallel calls — reduced latency 50%",
|
||||
scope="learning",
|
||||
title="Parallel async calls",
|
||||
)
|
||||
```
|
||||
|
||||
## Struggle (Problem/Solution)
|
||||
## Struggle (Problem / Blocker)
|
||||
|
||||
```python
|
||||
roboco_journal_struggle({
|
||||
task_id: task_id,
|
||||
problem: "Tests failing intermittently",
|
||||
attempts: ["Timeout increase", "Retry logic"],
|
||||
resolution: "Race condition in setup"
|
||||
})
|
||||
note(
|
||||
text=(
|
||||
"Tests failing intermittently — tried timeout increase and retry "
|
||||
"logic; root cause was a race condition in setup."
|
||||
),
|
||||
scope="struggle",
|
||||
task_id=task_id,
|
||||
)
|
||||
```
|
||||
|
||||
## Reflection (Required)
|
||||
## Reflection
|
||||
|
||||
Use a `reflect`-scope note before submitting to QA — it gives QA the
|
||||
"why" behind the diff.
|
||||
|
||||
```python
|
||||
roboco_journal_reflect({
|
||||
task_id: task_id,
|
||||
what_done: "Implemented rate limiting",
|
||||
what_learned: "Lua scripts for atomicity",
|
||||
what_struggled: "Testing concurrency"
|
||||
})
|
||||
note(
|
||||
text="Implemented rate limiting with a Redis-backed sliding window.",
|
||||
scope="reflect",
|
||||
task_id=task_id,
|
||||
what_done="Implemented rate limiting",
|
||||
what_learned="Lua scripts give atomicity for the counter increment",
|
||||
what_struggled="Testing concurrency deterministically",
|
||||
next_steps=["Add a load test for the 100-req boundary"],
|
||||
)
|
||||
```
|
||||
|
||||
## Reading Journals
|
||||
|
||||
Journals are written by `note` and surface through the knowledge base —
|
||||
there is no separate journal-read tool. Search past notes (yours and
|
||||
your team's, where permitted) via the `roboco-optimal` MCP server:
|
||||
|
||||
```python
|
||||
# Search your journal
|
||||
roboco_journal_search("rate limiting", top_k=5)
|
||||
# Semantic search over indexed notes/decisions/learnings
|
||||
roboco_kb_search(query="rate limiting", index_types=["journals", "decisions"])
|
||||
|
||||
# Recent entries
|
||||
roboco_journal_recent(limit=10)
|
||||
|
||||
# Read team journals (if permitted)
|
||||
roboco_journal_read_team(
|
||||
target_agent="be-dev-1",
|
||||
task_id=task_id
|
||||
)
|
||||
|
||||
# Your stats
|
||||
roboco_journal_stats()
|
||||
|
||||
# Check access scope
|
||||
roboco_journal_scope()
|
||||
# Conversational lookup with follow-up context
|
||||
roboco_ask_mentor(question="What did we decide about session storage?")
|
||||
```
|
||||
|
||||
@@ -1,84 +1,80 @@
|
||||
# Messaging Tools
|
||||
|
||||
## Sending Messages
|
||||
There is **no** `roboco_message_*`, `roboco_notify_send`, or
|
||||
`roboco_session_*` tool. Messaging is a small set of **content tools** on
|
||||
the `roboco-do` MCP server. They are role-scoped at spawn time.
|
||||
|
||||
## Channel post — `say`
|
||||
|
||||
```python
|
||||
roboco_message_send({
|
||||
channel: "backend-cell",
|
||||
content: "Starting work on rate limiting",
|
||||
task_id: task_id
|
||||
})
|
||||
say(channel="backend-cell", text="Starting work on rate limiting", task_id=task_id)
|
||||
```
|
||||
|
||||
## Channel History
|
||||
- `channel` is the slug WITHOUT a leading `#`.
|
||||
- `task_id` is auto-filled from your active task if omitted.
|
||||
- Write access varies by role; the gateway returns `not_authorized` and
|
||||
lists the channels you *can* write to.
|
||||
|
||||
Don't invent channel slugs. Call `channels()` first if unsure:
|
||||
|
||||
```python
|
||||
# Read channel history
|
||||
roboco_channel_history(
|
||||
channel="backend-cell",
|
||||
limit=50
|
||||
)
|
||||
channels() # -> {"writable": [...], "readable": [...]}
|
||||
```
|
||||
|
||||
## Notifications
|
||||
Valid slugs: cell channels (`backend-cell`, `frontend-cell`,
|
||||
`uxui-cell`); cross-cell (`dev-all`, `qa-all`, `pm-all`, `doc-all`);
|
||||
management (`main-pm-board`, `board-private`); broadcast
|
||||
(`announcements`, `all-hands`).
|
||||
|
||||
### Sending (PM/Board only)
|
||||
## Direct message (A2A) — `dm`
|
||||
|
||||
```python
|
||||
roboco_notify_send({
|
||||
recipient: "be-dev-1",
|
||||
type: "task_assignment",
|
||||
task_id: task_id,
|
||||
message: "Task ready for you"
|
||||
})
|
||||
dm(recipient="be-qa", text="Quick sanity check: ...", task_id=task_id)
|
||||
```
|
||||
|
||||
### Receiving
|
||||
- `recipient` is an agent slug (`be-pm`, `be-dev-1`, `ceo`, ...).
|
||||
- Auto-creates the conversation; `task_id` auto-fills from your active task.
|
||||
- Same-cell only. Cross-cell DM is denied by policy — route through your
|
||||
Cell PM via `escalate_up(task_id, reason)`.
|
||||
|
||||
## Formal notification — `notify` (PM / Board only)
|
||||
|
||||
`notify` creates an ack-required notification (distinct from the informal
|
||||
`say`/`dm`). Only PM roles and the Board may send it; devs / QA / docs use
|
||||
`say` and `dm`.
|
||||
|
||||
```python
|
||||
# List notifications
|
||||
notifications = roboco_notify_list()
|
||||
|
||||
# Acknowledge
|
||||
roboco_notify_ack(notification_id)
|
||||
notify(target="be-dev-1", text="Task ready for you", priority="normal", task_id=task_id)
|
||||
```
|
||||
|
||||
### Notification Types
|
||||
`priority` is `normal | high | urgent`. `task_id` auto-injects from the
|
||||
active task when omitted.
|
||||
|
||||
| Type | Purpose |
|
||||
|------|---------|
|
||||
| `task_assignment` | New task assigned |
|
||||
| `priority_change` | Priority updated |
|
||||
| `blocker_escalation` | Task blocked |
|
||||
| `review_request` | Review needed |
|
||||
| `documentation_request` | Docs needed |
|
||||
| `alert` | General alert |
|
||||
| `broadcast` | Org-wide message |
|
||||
## Receiving notifications
|
||||
|
||||
## Sessions
|
||||
Every role with an inbox gets these (so `i_am_idle()` doesn't soft-block
|
||||
on unread items):
|
||||
|
||||
```python
|
||||
# Create session for tasks
|
||||
roboco_session_create_for_tasks({
|
||||
title: "Feature X Implementation",
|
||||
task_ids: [task_1_id, task_2_id]
|
||||
})
|
||||
|
||||
# Start collaborative session
|
||||
roboco_session_start(
|
||||
channel="backend-cell",
|
||||
session_type="collaborative",
|
||||
task_id=task_id
|
||||
)
|
||||
notify_list(unread_only=True, limit=20) # your inbox
|
||||
notify_get(notification_id) # read one (marks it read)
|
||||
notify_ack(notification_id) # acknowledge after handling
|
||||
```
|
||||
|
||||
## Message Types
|
||||
When `i_am_idle()` reports unread A2A or @mentions, list -> get -> ack,
|
||||
then idle again. (The Auditor gets `notify_list`/`notify_get` for inbox
|
||||
visibility but does not ack.)
|
||||
|
||||
| Type | Use For |
|
||||
|------|---------|
|
||||
| `reasoning` | Thought process |
|
||||
| `dialogue` | Discussion |
|
||||
| `decision` | Decisions made |
|
||||
| `action` | Actions taken |
|
||||
| `blocker` | Blocking issues |
|
||||
| `technical` | Technical details |
|
||||
## Sessions (PM-or-up only)
|
||||
|
||||
Devs / QA / docs participate via channels and DMs and do **not** open
|
||||
sessions. PMs and the Board link discussion threads to tasks:
|
||||
|
||||
```python
|
||||
open_session(task_id, channel="backend-cell", topic="Feature X kickoff",
|
||||
relationship_type="discussion")
|
||||
link_session(session_id, task_id, is_primary=False)
|
||||
```
|
||||
|
||||
`relationship_type` is `discussion | planning | review | retrospective`.
|
||||
`link_session` is idempotent; you must own the task you're linking.
|
||||
|
||||
+47
-101
@@ -1,115 +1,61 @@
|
||||
# Project Tools
|
||||
# Project & Workspace Tools
|
||||
|
||||
## Overview
|
||||
|
||||
Project tools manage git repositories and agent workspaces.
|
||||
There is **no** `roboco_project_*` or `roboco_workspace_*` agent tool.
|
||||
Agents do **not** create projects, manage git tokens, or ensure
|
||||
workspaces. Those are handled for you:
|
||||
|
||||
## List Projects
|
||||
- **Workspaces are auto-cloned by the orchestrator** (`WorkspaceService`).
|
||||
Your per-agent clone of the project repo is created the first time you
|
||||
claim work on it — you never call a workspace tool. Branches are
|
||||
auto-created on `i_will_work_on()` / `claim_review()`; you don't run
|
||||
`git checkout` either.
|
||||
- **Project registration and git-token management are operator actions**
|
||||
done through the control panel / HTTP API, not from inside an agent
|
||||
container. Tokens are encrypted at rest; the agent container never sees
|
||||
the PAT (it is injected into git operations server-side and scrubbed
|
||||
from URLs).
|
||||
|
||||
## What a task already tells you
|
||||
|
||||
A task carries its project linkage; you don't look it up with a tool. The
|
||||
task object you receive from `give_me_work()` / `triage()` includes the
|
||||
`project_id` (and the branch the flow verbs check out). Acceptance
|
||||
criteria and the project context come back inline on the Envelope.
|
||||
|
||||
## Inspecting the repo
|
||||
|
||||
Read-only git inspection is available through the `roboco-git-readonly`
|
||||
MCP server (developers and QA):
|
||||
|
||||
```python
|
||||
roboco_project_list() # All accessible projects
|
||||
roboco_project_list(cell="backend") # Filter by cell
|
||||
roboco_git_status(project_slug="roboco")
|
||||
roboco_git_log(project_slug="roboco")
|
||||
roboco_git_diff(project_slug="roboco")
|
||||
roboco_git_branch_list(project_slug="roboco")
|
||||
```
|
||||
|
||||
Returns projects you have access to (cell-scoped for non-PMs).
|
||||
There is **no** `roboco_git_commit / _push / _checkout / _create_pr /
|
||||
_merge_pr` tool. Commits go through the `commit` content tool (auto-
|
||||
prefixed with `[task-id]`, auto-pushed by the choreographer); PRs open at
|
||||
`open_pr` time; merges are a PM `complete` operation.
|
||||
|
||||
## Get Project Details
|
||||
## Finding project knowledge
|
||||
|
||||
To learn how a project's codebase is laid out or how a subsystem works,
|
||||
query the knowledge base rather than a project tool:
|
||||
|
||||
```python
|
||||
roboco_project_get(slug="roboco")
|
||||
roboco_kb_search(query="rate limiting redis", project="roboco",
|
||||
index_types=["code", "documentation"])
|
||||
roboco_ask_mentor(question="How is auth wired up in this project?")
|
||||
```
|
||||
|
||||
Returns: `name`, `git_url`, `assigned_cell`, `default_branch`, `has_git_token`, `test_command`, etc.
|
||||
## PM note: creating work
|
||||
|
||||
**Note:** `has_git_token` indicates if authentication is configured (required for HTTPS repos).
|
||||
|
||||
## Create Project (PM+ Only)
|
||||
|
||||
```python
|
||||
# Example: register a separate frontend-only repo as a project.
|
||||
# (The built-in RoboCo control panel lives in this same repo under
|
||||
# panel/ and is NOT registered as a separate project.)
|
||||
roboco_project_create(
|
||||
name="Customer Portal",
|
||||
slug="customer-portal",
|
||||
git_url="https://github.com/org/customer-portal.git",
|
||||
assigned_cell="frontend",
|
||||
git_token="ghp_xxxx...", # GitHub PAT with repo scope
|
||||
default_branch="main",
|
||||
test_command="pnpm test",
|
||||
lint_command="pnpm lint"
|
||||
)
|
||||
```
|
||||
|
||||
**Who can create:** Main PM, Board, CEO
|
||||
|
||||
**IMPORTANT:** `git_token` is **required** for HTTPS repositories. Without it, workspace creation and git operations will fail.
|
||||
|
||||
## Update Project
|
||||
|
||||
```python
|
||||
roboco_project_update(
|
||||
slug="roboco-panel",
|
||||
git_token="ghp_newtoken...", # Update/rotate token
|
||||
test_command="pnpm test:ci",
|
||||
lint_command="pnpm lint:fix"
|
||||
)
|
||||
```
|
||||
|
||||
**Who can update:**
|
||||
- CEO, Main PM: Any project
|
||||
- Cell PM: Own cell's projects only
|
||||
|
||||
**Token rotation:** Pass `git_token` to update credentials. Pass empty string to clear.
|
||||
|
||||
## Workspace Tools
|
||||
|
||||
### Ensure Workspace
|
||||
|
||||
```python
|
||||
roboco_workspace_ensure(project_slug="roboco")
|
||||
```
|
||||
|
||||
Creates your workspace if it doesn't exist. Auto-clones the repository.
|
||||
|
||||
### Check Workspace Status
|
||||
|
||||
```python
|
||||
roboco_workspace_status(project_slug="roboco")
|
||||
```
|
||||
|
||||
Returns: `exists`, `branch`, `has_uncommitted`, `staged_files`, `unstaged_files`
|
||||
|
||||
### List Workspaces (PM Only)
|
||||
|
||||
```python
|
||||
roboco_workspace_list(project_slug="roboco")
|
||||
```
|
||||
|
||||
Lists all agent workspaces for a project. Cell PM sees own cell only.
|
||||
|
||||
## Permission Matrix
|
||||
|
||||
| Tool | Dev/QA/Doc | Cell PM | Main PM | CEO |
|
||||
|------|------------|---------|---------|-----|
|
||||
| `project_list` | Own cell | Own cell | All | All |
|
||||
| `project_get` | Yes | Yes | Yes | Yes |
|
||||
| `project_create` | No | No | Yes | Yes |
|
||||
| `project_update` | No | Own cell | All | All |
|
||||
| `workspace_ensure` | Yes | Yes | Yes | Yes |
|
||||
| `workspace_status` | Yes | Yes | Yes | Yes |
|
||||
| `workspace_list` | No | Own cell | All | All |
|
||||
|
||||
## Task Creation with Project
|
||||
|
||||
When creating tasks:
|
||||
|
||||
```python
|
||||
roboco_task_create(
|
||||
title="Add rate limiting",
|
||||
team="backend",
|
||||
project_slug="roboco", # Required - all tasks follow git workflow
|
||||
)
|
||||
```
|
||||
|
||||
Use `project_slug="roboco"` for internal RoboCo codebase work.
|
||||
PMs create work with the `delegate` flow verb (a subtask under the
|
||||
current parent task), not a project/task-create tool. `delegate` takes an
|
||||
optional `project_id`; the parent task's project is inherited when you
|
||||
omit it. There is no agent-facing standalone project- or task-create
|
||||
tool.
|
||||
|
||||
+107
-86
@@ -1,111 +1,132 @@
|
||||
# Task Management Tools
|
||||
|
||||
## Core Operations
|
||||
There is **no** `roboco_task_*` tool surface. Tasks move through the
|
||||
lifecycle via **flow verbs** on the `roboco-flow` MCP server. Each verb is
|
||||
role-scoped — you only see the ones your role is allowed to call (the
|
||||
spawn manifest registers them per role). Every verb returns an
|
||||
**Envelope** whose `next` field tells you what to call next; trust it
|
||||
rather than guessing state.
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_task_get` | Get task details |
|
||||
| `roboco_task_scan` | Find available tasks |
|
||||
| `roboco_task_claim` | Take ownership |
|
||||
| `roboco_task_unclaim` | Release claimed task |
|
||||
| `roboco_task_start` | Begin work |
|
||||
The verbs below are grouped by who calls them.
|
||||
|
||||
## Task Retrieval
|
||||
## Developer flow
|
||||
|
||||
```python
|
||||
# Get specific task
|
||||
task = roboco_task_get(task_id)
|
||||
|
||||
# Scan for available tasks
|
||||
tasks = roboco_task_scan(
|
||||
team="backend", # Optional filter
|
||||
status="pending" # Optional filter
|
||||
)
|
||||
give_me_work() # returns your most-actionable pending task
|
||||
i_will_work_on(task_id, plan="...")
|
||||
# claims + sets plan + starts; auto-creates and
|
||||
# checks out feature/{team}/{task-hierarchy}
|
||||
commit(message, files=None) # content tool — repeat per change (auto-pushed)
|
||||
open_pr(task_id) # pushes branch + opens the PR
|
||||
i_am_done(task_id, notes="") # verifying -> awaiting_qa (PR must already be open)
|
||||
i_am_blocked(task_id, reason) # external dependency; cell PM unblocks
|
||||
unclaim(task_id) # release a claimed task back to the queue
|
||||
resume(task_id) # recover a paused task after compact/restart
|
||||
i_am_idle() # no work in your queue right now
|
||||
```
|
||||
|
||||
## Task Lifecycle
|
||||
There is no separate claim / start / pause verb — `i_will_work_on`
|
||||
composes claim + set-plan + start atomically, and `i_am_done` composes
|
||||
verify + submit-qa. Branches are auto-created on `i_will_work_on`; do not
|
||||
checkout by hand.
|
||||
|
||||
## QA flow
|
||||
|
||||
```python
|
||||
# Claim task
|
||||
roboco_task_claim(task_id)
|
||||
|
||||
# Release if you shouldn't work on it
|
||||
roboco_task_unclaim(task_id)
|
||||
roboco_task_unclaim(task_id, hand_off_to="be-dev-2")
|
||||
|
||||
# Start work (also resumes paused tasks)
|
||||
roboco_task_start(task_id)
|
||||
|
||||
# Pause work
|
||||
roboco_task_pause(task_id, reason="Waiting for clarification")
|
||||
|
||||
# Resume paused work (use start)
|
||||
roboco_task_start(task_id) # Works on paused tasks
|
||||
|
||||
# Block (waiting on another task)
|
||||
roboco_task_block(task_id, blocker_task_id, reason)
|
||||
|
||||
# Unblock (PM only)
|
||||
roboco_task_unblock(task_id)
|
||||
give_me_work() # returns an awaiting_qa task
|
||||
claim_review(task_id) # claim for review (auto-checks-out dev branch)
|
||||
pass(task_id, notes) # awaiting_qa -> awaiting_documentation
|
||||
fail(task_id, issues=[...]) # awaiting_qa -> needs_revision (dev gets it back)
|
||||
unclaim(task_id) / resume(task_id) / i_am_idle()
|
||||
```
|
||||
|
||||
## Submission
|
||||
`notes` (on pass) and `issues` (on fail) must be substantive — the
|
||||
enforcement layer rejects empty or near-empty content. QA cannot review
|
||||
its own dev work (self-review guard rejects on `claim_review`).
|
||||
|
||||
## Documenter flow
|
||||
|
||||
```python
|
||||
# Submit for verification
|
||||
roboco_task_submit_verification(task_id)
|
||||
|
||||
# Submit for QA
|
||||
roboco_task_submit_qa(task_id, notes)
|
||||
|
||||
# QA actions
|
||||
roboco_task_qa_pass(task_id, {notes: "..."})
|
||||
roboco_task_qa_fail(task_id, {notes: "...", issues: [...]})
|
||||
|
||||
# Documentation complete
|
||||
roboco_task_docs_complete(task_id)
|
||||
|
||||
# PM complete
|
||||
roboco_task_complete(task_id)
|
||||
give_me_work() # returns an awaiting_documentation task
|
||||
claim_doc_task(task_id) # claim the doc phase
|
||||
commit(message, files) # commit the doc files you write
|
||||
i_documented(task_id, notes, files)
|
||||
# awaiting_documentation -> awaiting_pm_review
|
||||
```
|
||||
|
||||
## PM Operations
|
||||
Documentation tasks are **not** delegated — the lifecycle auto-creates
|
||||
the doc phase after a code task passes QA.
|
||||
|
||||
## Cell PM flow
|
||||
|
||||
```python
|
||||
# Create SUBTASK (most common)
|
||||
roboco_task_create({
|
||||
title: "Implement auth endpoint",
|
||||
parent_task_id: my_task_id, # REQUIRED for subtasks
|
||||
team: "backend",
|
||||
assigned_to: "be-dev-1" # Use SLUG
|
||||
})
|
||||
|
||||
# Create standalone task (rare)
|
||||
roboco_task_create({
|
||||
title: "...",
|
||||
team: "backend",
|
||||
status: "backlog"
|
||||
})
|
||||
|
||||
# Activate (backlog -> pending)
|
||||
roboco_task_activate(task_id)
|
||||
|
||||
# Cancel
|
||||
roboco_task_cancel(task_id, reason)
|
||||
|
||||
# Plan
|
||||
roboco_task_plan(task_id, approach, steps)
|
||||
|
||||
# Escalate to CEO (parent tasks only)
|
||||
roboco_task_escalate_to_ceo(task_id, notes)
|
||||
triage() # list actionable tasks in your cell
|
||||
i_will_plan(task_id, plan, approach)
|
||||
# claim + plan + start a parent task
|
||||
delegate(parent_task_id, title, description, assigned_to, team,
|
||||
task_type, nature, estimated_complexity, acceptance_criteria)
|
||||
# create a subtask under the current task
|
||||
unblock(task_id) # blocked -> in_progress (PM only)
|
||||
submit_up(task_id, notes) # open cell->root PR; -> awaiting_pm_review
|
||||
complete(task_id, notes) # awaiting_pm_review -> completed (merges leaf PR)
|
||||
escalate_up(task_id, reason) # escalate to your escalation target
|
||||
```
|
||||
|
||||
**CRITICAL**: When creating subtasks, ALWAYS include `parent_task_id`. Without it, you create orphan sibling tasks instead of linked subtasks.
|
||||
**Delegation rules** (enforced): `main_pm -> cell_pm`; `cell_pm -> its
|
||||
team's devs`. Cell PMs receive planning-typed parent tasks; devs get
|
||||
code/research (UX devs also design). Always create subtasks via
|
||||
`delegate` with `parent_task_id` set — there is no standalone task-create
|
||||
verb for agents.
|
||||
|
||||
**Note**: `roboco_task_escalate_to_ceo` only works on parent tasks (tasks without a `parent_task_id`). Subtasks must have their parent task escalated instead.
|
||||
## Main PM flow
|
||||
|
||||
## Progress Updates
|
||||
The Main PM has the Cell PM verbs **plus**:
|
||||
|
||||
```python
|
||||
roboco_task_progress(task_id, "Implementing API", 50)
|
||||
triage_all() # list actionable tasks across all teams
|
||||
escalate_to_ceo(task_id, reason)
|
||||
# awaiting_pm_review -> awaiting_ceo_approval
|
||||
give_me_work() # Main PM may also pull work directly
|
||||
```
|
||||
|
||||
`complete` for the Main PM merges the **root** PR. Only the CEO merges to
|
||||
`master`; agents stop at `escalate_to_ceo`.
|
||||
|
||||
## Board flow (Product Owner / Head of Marketing)
|
||||
|
||||
```python
|
||||
triage() # list actionable tasks in scope
|
||||
escalate_to_ceo(task_id, reason)
|
||||
i_am_idle()
|
||||
```
|
||||
|
||||
The Board **cannot** claim, create, complete, or cancel tasks. Strategic
|
||||
decisions are escalated to the CEO.
|
||||
|
||||
## Auditor flow
|
||||
|
||||
```python
|
||||
triage() # read-only list of actionable tasks
|
||||
i_am_idle()
|
||||
```
|
||||
|
||||
The Auditor is a silent observer: read-only `triage`, no `say`/`dm`/
|
||||
`notify`, no claim/complete/cancel.
|
||||
|
||||
## Cancel
|
||||
|
||||
Cancelling a task (any non-terminal status -> `cancelled`) is restricted
|
||||
to **PM roles and the CEO**. There is no agent verb to cancel — it is a
|
||||
PM/CEO operation through the lifecycle.
|
||||
|
||||
## Progress
|
||||
|
||||
Record progress against your plan with the `progress` content tool (on
|
||||
`roboco-do`), not a task verb:
|
||||
|
||||
```python
|
||||
progress(task_id, message="API skeleton landed", plan_step="2")
|
||||
```
|
||||
|
||||
Your plan's steps are the progress checklist; the percentage is derived
|
||||
from completed steps — you do not set it.
|
||||
|
||||
Reference in New Issue
Block a user