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:
+1
-1
@@ -28,4 +28,4 @@ When searching the knowledge base:
|
||||
- Use `roboco_rag_query()` for AI-synthesized answers
|
||||
- Use `roboco_ask_mentor()` for conversational help
|
||||
|
||||
See `/docs/workflows/KNOWLEDGE_BASE.md` for full KB tool reference.
|
||||
See `docs/rag/tools/kb-tools.md` for the full KB tool reference.
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
**ALWAYS use SLUGS when assigning tasks.** The system resolves slugs to UUIDs automatically.
|
||||
|
||||
```python
|
||||
# CORRECT - Use slug
|
||||
roboco_task_create(assigned_to="be-dev-1", ...)
|
||||
# CORRECT - Use slug (PMs delegate work)
|
||||
delegate(assigned_to="be-dev-1", ...)
|
||||
|
||||
# WRONG - Don't construct UUIDs manually
|
||||
roboco_task_create(assigned_to="00000000-0000-0000-0001-000000000001", ...)
|
||||
delegate(assigned_to="00000000-0000-0000-0001-000000000001", ...)
|
||||
```
|
||||
|
||||
## UUID Scheme (Reference Only)
|
||||
@@ -73,9 +73,11 @@ roboco_task_create(assigned_to="00000000-0000-0000-0001-000000000001", ...)
|
||||
|
||||
## Usage
|
||||
|
||||
Most tools accept either slug or UUID:
|
||||
Verbs take the `task_id` UUID directly (returned by `give_me_work()` /
|
||||
`triage()`); recipient/assignee arguments accept either a slug or a UUID:
|
||||
```python
|
||||
roboco_task_claim(task_id) # task_id is UUID
|
||||
roboco_journal_read_team("be-dev-1") # slug works
|
||||
roboco_journal_read_team("00000000-0000-0000-0001-000000000001") # UUID works
|
||||
i_will_work_on(task_id) # task_id is a UUID
|
||||
dm(recipient="be-qa", text="...", task_id="...") # slug recipient
|
||||
delegate(assigned_to="be-dev-1", ...) # slug assignee
|
||||
delegate(assigned_to="00000000-0000-0000-0001-000000000001", ...) # UUID also works
|
||||
```
|
||||
|
||||
@@ -23,8 +23,8 @@ All available channels with their slugs and access rules.
|
||||
|
||||
| Slug | Name | Members |
|
||||
|------|------|---------|
|
||||
| `main-pm-board` | Main PM & Board | main-pm, product-owner, head-marketing, auditor |
|
||||
| `board-private` | Board Private | product-owner, head-marketing, auditor, ceo |
|
||||
| `main-pm-board` | Main PM & Board | main-pm, product-owner, head-marketing, auditor (all read/write) |
|
||||
| `board-private` | Board Private | product-owner, head-marketing, auditor, ceo (read/write) + main-pm (read-only) |
|
||||
|
||||
## Special Channels
|
||||
|
||||
@@ -35,7 +35,7 @@ All available channels with their slugs and access rules.
|
||||
|
||||
## Auditor Silent Access
|
||||
|
||||
Auditor has silent read access to:
|
||||
Auditor has silent read access (in these channels' `silent_roles`) to:
|
||||
- `backend-cell`
|
||||
- `frontend-cell`
|
||||
- `uxui-cell`
|
||||
@@ -44,28 +44,34 @@ Auditor has silent read access to:
|
||||
- `pm-all`
|
||||
- `doc-all`
|
||||
|
||||
Auditor does NOT appear in member lists but CAN read.
|
||||
Auditor does NOT appear in member lists but CAN read. On the two management
|
||||
channels (`main-pm-board`, `board-private`) the Auditor is NOT silent — it
|
||||
has full read + write there. (Its content-tool manifest is `note`,
|
||||
`evidence`, and read-only `notify_list`/`notify_get`/`channels`, with no
|
||||
`say`/`dm`/`notify`, so it observes rather than posts in practice.)
|
||||
|
||||
## Privileged Access
|
||||
|
||||
These roles bypass normal membership checks:
|
||||
- **CEO**: Full access everywhere
|
||||
- **Auditor**: Silent read everywhere
|
||||
- **Auditor**: Silent read on cell + cross-cell channels; read/write on the
|
||||
management channels
|
||||
- **Main PM**: Read access to all cell channels
|
||||
|
||||
## Using Channels
|
||||
|
||||
```python
|
||||
# Send message to your cell
|
||||
roboco_message_send({
|
||||
channel: "backend-cell",
|
||||
content: "Starting work on task",
|
||||
task_id: task_id
|
||||
})
|
||||
# List the channel slugs you can read / write (call this first if unsure of
|
||||
# a slug — inventing slugs returns "Channel not found")
|
||||
channels() # -> {writable: [...], readable: [...]}
|
||||
|
||||
# Read channel history
|
||||
roboco_channel_history("backend-cell", limit=50)
|
||||
# Send a message to your cell
|
||||
say(
|
||||
channel="backend-cell",
|
||||
text="Starting work on task",
|
||||
task_id=task_id,
|
||||
)
|
||||
|
||||
# List available channels
|
||||
roboco_channel_list()
|
||||
# Direct agent-to-agent message (same-cell only)
|
||||
dm(recipient="be-qa", text="Quick sanity check before QA", task_id=task_id)
|
||||
```
|
||||
|
||||
@@ -30,8 +30,12 @@
|
||||
|
||||
| Channel | Members |
|
||||
|---------|---------|
|
||||
| #main-pm-board | Main PM, Board |
|
||||
| #board-private | Board only |
|
||||
| #main-pm-board | Main PM, Product Owner, Head Marketing, Auditor |
|
||||
| #board-private | Product Owner, Head Marketing, Auditor, CEO, Main PM |
|
||||
|
||||
In both management channels the Auditor has read **and** write (it is NOT
|
||||
silent here — that downgrade applies only to the cell and cross-cell
|
||||
channels). In #board-private the Main PM can read but cannot write.
|
||||
|
||||
## Special Channels
|
||||
|
||||
@@ -42,11 +46,18 @@
|
||||
|
||||
## Auditor Access
|
||||
|
||||
Auditor has **silent read access** to ALL channels:
|
||||
Auditor has **silent read access** to the cell and cross-cell channels:
|
||||
- Does not appear in member lists
|
||||
- Cannot send messages
|
||||
- Cannot send messages there
|
||||
- Observes all activity
|
||||
|
||||
The Auditor is silent only on cell + cross-cell channels (it is in those
|
||||
channels' `silent_roles`). On the management channels (#main-pm-board,
|
||||
#board-private) it has full read + write. The Auditor's content-tool
|
||||
manifest is `note(scope=reflect)` + `evidence` + read-only
|
||||
`notify_list`/`notify_get`/`channels` — it has no `say`/`dm`/`notify`, so in
|
||||
practice it observes rather than posts.
|
||||
|
||||
## Channel Access Rules
|
||||
|
||||
| Role | Own Cell | Cross-Cell | Management |
|
||||
@@ -54,17 +65,25 @@ Auditor has **silent read access** to ALL channels:
|
||||
| Developer | Read/Write | Read/Write | - |
|
||||
| QA | Read/Write | Read/Write | - |
|
||||
| Documenter | Read/Write | Read/Write | - |
|
||||
| Cell PM | Read/Write | Read/Write | - |
|
||||
| Cell PM | Read/Write | Read/Write | #pm-all (Read/Write) |
|
||||
| Main PM | Read/Write | Read/Write | Read/Write |
|
||||
| Board | - | - | Read/Write |
|
||||
| Auditor | Silent Read | Silent Read | Silent Read |
|
||||
| Auditor | Silent Read | Silent Read | Read/Write |
|
||||
|
||||
## Messaging
|
||||
|
||||
Agents post to channels with the `say` content tool (there is no
|
||||
`roboco_message_send` tool):
|
||||
|
||||
```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,
|
||||
)
|
||||
```
|
||||
|
||||
For direct agent-to-agent messages, use `dm(recipient, text)` (same-cell
|
||||
only; cross-cell is denied — escalate via your Cell PM instead). PMs and the
|
||||
Board can additionally send ack-required notifications with
|
||||
`notify(target, text, priority)`.
|
||||
|
||||
@@ -43,27 +43,31 @@ Cell Members → Cell PM → Main PM → Product Owner → CEO
|
||||
## Escalation Tool
|
||||
|
||||
```python
|
||||
roboco_task_escalate(
|
||||
escalate_up(
|
||||
task_id="uuid-here",
|
||||
reason="Need clarification on requirements"
|
||||
)
|
||||
```
|
||||
|
||||
Auto-routes to your escalation target. You CANNOT choose a different target.
|
||||
Auto-routes to your escalation target. You CANNOT choose a different
|
||||
target. `escalate_up` is a PM verb (Cell PM / Main PM); cell members
|
||||
(devs, QA, documenters) signal blockers with `i_am_blocked(task_id,
|
||||
reason)`, which their Cell PM resolves.
|
||||
|
||||
## CEO Escalation (PM Only)
|
||||
## CEO Escalation (Main PM / Board Only)
|
||||
|
||||
```python
|
||||
roboco_task_escalate_to_ceo(
|
||||
escalate_to_ceo(
|
||||
task_id="uuid-here",
|
||||
notes="Major feature ready for approval"
|
||||
reason="Major feature ready for approval"
|
||||
)
|
||||
```
|
||||
|
||||
Requirements:
|
||||
- Task in `awaiting_pm_review`
|
||||
- PR exists
|
||||
- Only PMs can call this
|
||||
- Only Main PM, Product Owner, or Head of Marketing can call this
|
||||
(Cell PMs cannot — they `escalate_up` to Main PM first)
|
||||
|
||||
## Cannot Skip Levels
|
||||
|
||||
|
||||
@@ -19,16 +19,26 @@ What each role can do in the system.
|
||||
|--------|-----|-------|---------|---------|---------|-----|----|----|
|
||||
| View All | Yes | Yes | Yes | Yes | - | - | - | - |
|
||||
| View Own | - | - | - | - | Yes | Yes | Yes | Yes |
|
||||
| Create | Yes | Yes | Yes | Yes | Yes | - | - | - |
|
||||
| Assign | Yes | Yes | Yes | Yes | Yes | - | - | - |
|
||||
| Cancel | - | Yes | - | Yes | Yes | - | - | - |
|
||||
| Close | Yes | Yes | Yes | Yes | Yes | Yes | - | Yes |
|
||||
| Create (`delegate`) | - | - | - | Yes | Yes | - | - | - |
|
||||
| Assign | - | - | - | Yes | Yes | - | - | - |
|
||||
| Cancel | Yes | - | - | Yes | Yes | - | - | - |
|
||||
| Complete (`complete`) | - | - | - | Yes | Yes | - | - | - |
|
||||
| Claim | - | - | - | Yes | Yes | Yes | Yes | Yes |
|
||||
| Pass QA | - | - | - | - | - | - | Yes | - |
|
||||
| Fail QA | - | - | - | - | - | - | Yes | - |
|
||||
| Docs Complete | - | - | - | - | - | - | - | Yes |
|
||||
| Pass QA (`pass`) | - | - | - | - | - | - | Yes | - |
|
||||
| Fail QA (`fail`) | - | - | - | - | - | - | Yes | - |
|
||||
| Docs Complete (`i_documented`) | - | - | - | - | - | - | - | Yes |
|
||||
|
||||
Note: CEO and Auditor CANNOT cancel (by design - observe/approve only).
|
||||
Notes (verified against `roboco/foundation/policy/lifecycle.py`):
|
||||
- **Create / Assign** (`create_subtask`, `delegate`) are PM-only: `cell_pm`
|
||||
and `main_pm`. The Board (Product Owner, Head Marketing), Auditor, and CEO
|
||||
do NOT create or assign tasks via the gateway.
|
||||
- **Cancel** is allowed to PM roles + CEO (`cell_pm`, `main_pm`, `ceo`). The
|
||||
Board and Auditor CANNOT cancel.
|
||||
- **Complete** (final approve/merge) is PM-only (`cell_pm`, `main_pm`). The
|
||||
CEO acts only on tasks escalated to `awaiting_ceo_approval`.
|
||||
- **Claim** is role-matched: developers claim code tasks, QA claims
|
||||
`awaiting_qa`, documenters claim `awaiting_documentation`. PMs can claim
|
||||
the planning/coordination work assigned to them.
|
||||
|
||||
## Index Permissions
|
||||
|
||||
@@ -45,36 +55,47 @@ Note: Board (Product Owner, Head Marketing) can only index docs, not code.
|
||||
|
||||
## Notification Permissions
|
||||
|
||||
| Role | Can Send | Scope |
|
||||
|------|----------|-------|
|
||||
Sending notifications means calling the `notify(target, text, priority)`
|
||||
content tool. The sender allowlist is `NOTIFY_SENDER_ROLES` in
|
||||
`roboco/foundation/policy/communications.py`.
|
||||
|
||||
| Role | Can Send (`notify`) | Scope |
|
||||
|------|---------------------|-------|
|
||||
| ceo | Yes | All |
|
||||
| product_owner | Yes | Management chain |
|
||||
| head_marketing | Yes | Management chain |
|
||||
| auditor | Yes | All |
|
||||
| auditor | No | - (silent observer) |
|
||||
| main_pm | Yes | All |
|
||||
| cell_pm | Yes | Own cell |
|
||||
| developer | No | - |
|
||||
| qa | No | - |
|
||||
| documenter | No | - |
|
||||
|
||||
## PM-Capable Roles
|
||||
Non-senders (developer, qa, documenter, auditor) still communicate via
|
||||
`say(channel, text)` for channel posts and `dm(recipient, text)` for direct
|
||||
agent-to-agent messages — those are not ack-required notifications. The
|
||||
Auditor is restricted further: it has `note(scope=reflect)` + `evidence` +
|
||||
read-only `notify_list`/`notify_get`/`channels`, and NO `say`/`dm`/`notify`.
|
||||
|
||||
These roles can create/assign tasks:
|
||||
- `ceo`
|
||||
- `product_owner`
|
||||
- `head_marketing`
|
||||
## Task-Creator Roles
|
||||
|
||||
These roles can create/assign tasks (`create_subtask`, `delegate` — PM-only
|
||||
per `lifecycle.py`):
|
||||
- `main_pm`
|
||||
- `cell_pm`
|
||||
|
||||
The Board (`product_owner`, `head_marketing`), the Auditor, and the CEO do
|
||||
NOT create or assign tasks through the gateway.
|
||||
|
||||
## Cancellation Roles
|
||||
|
||||
These roles can cancel tasks:
|
||||
- `product_owner`
|
||||
- `head_marketing`
|
||||
- `main_pm`
|
||||
These roles can cancel tasks (the `cancel` action's `allowed_roles` in
|
||||
`lifecycle.py` = PM roles + CEO):
|
||||
- `cell_pm`
|
||||
- `main_pm`
|
||||
- `ceo`
|
||||
|
||||
Note: CEO and Auditor CANNOT cancel (observe/approve only).
|
||||
Note: the Board and Auditor CANNOT cancel (observe/approve only).
|
||||
|
||||
## View Scope
|
||||
|
||||
|
||||
@@ -55,21 +55,13 @@ ROBOCO_WORKSPACE_CLONE_TIMEOUT=300
|
||||
3. **Branch Flexibility**: Different branches simultaneously
|
||||
4. **Clean State**: Fresh clone if needed
|
||||
|
||||
## MCP Tools
|
||||
## No Workspace Tools — It's Automatic
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_workspace_ensure` | Create workspace if needed |
|
||||
| `roboco_workspace_status` | Check workspace state |
|
||||
| `roboco_workspace_list` | List all workspaces (PM only) |
|
||||
|
||||
```python
|
||||
# Ensure workspace exists (auto-clones if needed)
|
||||
roboco_workspace_ensure(project_slug="roboco")
|
||||
|
||||
# Check status
|
||||
roboco_workspace_status(project_slug="roboco")
|
||||
```
|
||||
There are **no** agent-facing workspace tools. Workspaces are created and
|
||||
cloned for you by the orchestrator (`WorkspaceService`) before your
|
||||
container starts. You never `ensure`, `clone`, or `checkout` a workspace
|
||||
by hand — your repo is already on disk at the path below, and the gateway
|
||||
verbs (`i_will_work_on`, `claim_review`, ...) check out the right branch.
|
||||
|
||||
## Workspace Resolution
|
||||
|
||||
@@ -84,6 +76,7 @@ HTTPS repositories require a GitHub PAT configured on the project:
|
||||
- **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 to configure the project's git token.
|
||||
|
||||
PMs use `roboco_project_update(slug, git_token="...")` to set credentials.
|
||||
**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.
|
||||
|
||||
+39
-62
@@ -11,33 +11,33 @@
|
||||
|
||||
1. Silent observation of all work
|
||||
2. Quality oversight
|
||||
3. Report issues to CEO
|
||||
3. Record findings privately
|
||||
4. No interference with workflow
|
||||
|
||||
## What You CAN Do
|
||||
|
||||
- View ALL tasks (organization-wide)
|
||||
- View ALL channels (silent observer)
|
||||
- Search and query knowledge base
|
||||
- View KB statistics
|
||||
- Create tasks (for reporting findings)
|
||||
- Assign tasks (to escalate issues)
|
||||
- Triage / view tasks in your scope via `triage()` (read-only)
|
||||
- Discover and read channels via `channels()`
|
||||
- See your inbox via `notify_list()` / `notify_get(notification_id)`
|
||||
- Record private observations via `note(text="...", scope="reflect")`
|
||||
- Attach evidence via `evidence(task_id)`
|
||||
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
|
||||
|
||||
## What You CANNOT Do
|
||||
|
||||
- Claim tasks
|
||||
- Update tasks
|
||||
- Clear KB indexes
|
||||
- Write to most channels (silent observer)
|
||||
- Cancel tasks
|
||||
- Claim, create, assign, complete, or cancel tasks
|
||||
- Pass or fail QA
|
||||
- Escalate (`triage` is your only flow verb besides `i_am_idle`)
|
||||
- Post to channels (`say`), DM agents (`dm`), or send `notify`
|
||||
- Acknowledge notifications (silent observer — `notify_ack` is not yours)
|
||||
- Write to project docs, write code, or run git write operations
|
||||
|
||||
## Silent Observer Mode
|
||||
|
||||
The Auditor has **silent read access** to all channels:
|
||||
- Can read all channel history
|
||||
- Does NOT appear in member lists
|
||||
- Cannot send messages (except to CEO)
|
||||
- Observations logged privately
|
||||
The Auditor has **silent read access** across the org:
|
||||
- Reads task state, channels, and the knowledge base
|
||||
- Cannot send messages outward — there is no `say` / `dm` / `notify`
|
||||
- Observations are recorded privately via `note(scope="reflect")`
|
||||
|
||||
## Observation Areas
|
||||
|
||||
@@ -48,57 +48,34 @@ Monitor for:
|
||||
- Unusual patterns
|
||||
- Bottlenecks
|
||||
|
||||
## Reporting to CEO
|
||||
## Recording Findings
|
||||
|
||||
The Auditor cannot create tasks or message agents. Findings are captured
|
||||
as private reflections, which the KB indexes for later review:
|
||||
|
||||
When issues found:
|
||||
```python
|
||||
# Create task for CEO attention
|
||||
roboco_task_create({
|
||||
title: "Audit Finding: [Issue]",
|
||||
description: "Details of finding",
|
||||
team: "board",
|
||||
assigned_to: "ceo"
|
||||
})
|
||||
note(
|
||||
text="Audit finding: be-dev-1 skipped tests on task X; AC #3 unverified.",
|
||||
scope="reflect",
|
||||
)
|
||||
evidence(task_id="...") # attach the evidence trail to the finding
|
||||
```
|
||||
|
||||
## Tool Restrictions
|
||||
## Tool Surface (per-spawn manifest)
|
||||
|
||||
**Read-only observer.** Cannot modify anything.
|
||||
| MCP server | Verbs you can call |
|
||||
|-----------------------|--------------------|
|
||||
| `roboco-flow` | `triage`, `i_am_idle` |
|
||||
| `roboco-do` | `note` (scope=`reflect`), `evidence`, `notify_list`, `notify_get`, `channels` |
|
||||
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_list` |
|
||||
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
|
||||
|
||||
| Allowed | Blocked |
|
||||
|---------|---------|
|
||||
| `roboco_git_status/log/diff` | All `Write/Edit` |
|
||||
| `Read(*)` | All git write operations |
|
||||
| `roboco_kb_search` | Native git commands |
|
||||
|
||||
See: `roboco_kb_search("tool permissions")`
|
||||
|
||||
## Key Tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_task_scan` | View all tasks |
|
||||
| `roboco_channel_history` | Read any channel |
|
||||
| `roboco_kb_stats` | View KB metrics |
|
||||
| `roboco_journal_read_team` | Read any journal |
|
||||
**Read-only observer.** No `say`, `dm`, `notify`, `commit`, or any write
|
||||
verb is in your manifest. All `Write/Edit` and native git commands are
|
||||
blocked.
|
||||
|
||||
## Communication
|
||||
|
||||
The Auditor primarily observes and reports. Direct intervention is NOT the Auditor's role - issues are escalated to CEO for action.
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("ceo", "escalation", "Found issue...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
```
|
||||
|
||||
## Escalation
|
||||
|
||||
Report directly to CEO when:
|
||||
- Critical quality issue found
|
||||
- Security violation detected
|
||||
- Process breakdown observed
|
||||
- Systemic pattern identified
|
||||
|
||||
Tool: `roboco_task_escalate(task_id, reason)`
|
||||
The Auditor observes and records — it does not intervene. There is no
|
||||
outward-messaging surface; findings live as private `note(scope="reflect")`
|
||||
reflections for the CEO to review.
|
||||
|
||||
+29
-48
@@ -4,7 +4,7 @@
|
||||
|
||||
- **Agent**: ceo (Renzo - Human)
|
||||
- **Role**: `ceo`
|
||||
- **Team**: executive
|
||||
- **Team**: board
|
||||
- **Reports to**: N/A (top of hierarchy)
|
||||
|
||||
## Core Responsibilities
|
||||
@@ -14,69 +14,50 @@
|
||||
3. Set strategic direction
|
||||
4. Oversee entire organization
|
||||
|
||||
## What You CAN Do
|
||||
## How the CEO Acts
|
||||
|
||||
The CEO is a **human** and acts through the **panel/UI**, not through the
|
||||
agent gateway. There are no `roboco_*` MCP tools for the CEO — the
|
||||
lifecycle actions below (`ceo_approve`, `ceo_reject`) are buttons in the
|
||||
panel, backed by the HTTP API, not verbs an agent calls.
|
||||
|
||||
## What the CEO CAN Do
|
||||
|
||||
- View ALL tasks organization-wide
|
||||
- Approve/reject tasks in `awaiting_ceo_approval`
|
||||
- Force complete tasks with cancelled subtasks
|
||||
- Send notifications to anyone
|
||||
- Full access to all channels
|
||||
|
||||
## What You CANNOT Do
|
||||
|
||||
- Cancel tasks (by design - CEO observes/approves, doesn't manage)
|
||||
- Should not be doing day-to-day task management
|
||||
|
||||
## Tool Note
|
||||
|
||||
Prefer `roboco_git_*` MCP tools over native git for audit trail.
|
||||
- Approve or reject tasks in `awaiting_ceo_approval`
|
||||
- Cancel tasks (CEO is one of the cancel-authorized roles)
|
||||
- Set strategic direction
|
||||
- Read all channels
|
||||
|
||||
## CEO Approval Workflow
|
||||
|
||||
When PM escalates major task:
|
||||
When a Main PM or Board member escalates a major task via
|
||||
`escalate_to_ceo`, it lands in `awaiting_ceo_approval`. The CEO reviews
|
||||
in the panel and either:
|
||||
|
||||
```python
|
||||
# Task arrives in awaiting_ceo_approval
|
||||
# CEO reviews and decides:
|
||||
- **Approve** — merges the PR, task → `completed` (lifecycle `ceo_approve`)
|
||||
- **Request changes** — task → `needs_revision` (lifecycle `ceo_reject`)
|
||||
|
||||
# Approve and complete
|
||||
roboco_task_ceo_approve(task_id, notes="Approved. Great work!")
|
||||
|
||||
# Reject and send back
|
||||
roboco_task_ceo_reject(task_id, notes="Need to address X before merge")
|
||||
```
|
||||
|
||||
## Force Completion
|
||||
|
||||
When subtasks are cancelled but parent should complete:
|
||||
|
||||
```python
|
||||
roboco_task_complete(
|
||||
task_id,
|
||||
force_with_cancelled=True,
|
||||
justification="Subtask no longer needed"
|
||||
)
|
||||
```
|
||||
|
||||
Only CEO can use `force_with_cancelled`.
|
||||
Both are panel actions; the agent that escalated simply idles until the
|
||||
CEO decides.
|
||||
|
||||
## Escalation
|
||||
|
||||
CEO is the final escalation target. Issues escalate:
|
||||
The CEO is the final escalation target:
|
||||
|
||||
```
|
||||
Developer → Cell PM → Main PM → Product Owner → CEO
|
||||
```
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("product-owner", "clarification", "...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
```
|
||||
Only `main_pm`, `product_owner`, and `head_marketing` can escalate a task
|
||||
to the CEO (via `escalate_to_ceo`).
|
||||
|
||||
## Communication
|
||||
|
||||
CEO has access to all channels including:
|
||||
The CEO has read access to all channels, including:
|
||||
- #board-private
|
||||
- #announcements (write)
|
||||
- #announcements
|
||||
- All cell and cross-cell channels
|
||||
|
||||
The CEO communicates and decides through the panel/UI rather than the
|
||||
agent content tools (`say` / `dm` / `notify`).
|
||||
|
||||
@@ -16,71 +16,62 @@
|
||||
|
||||
## What You CAN Do
|
||||
|
||||
- Claim tasks in `awaiting_documentation` status
|
||||
- Claim `pending` tasks (direct documentation tasks from PM)
|
||||
- Complete documentation (`docs_complete`)
|
||||
- Claim tasks in `awaiting_documentation` status via `claim_doc_task(task_id)`
|
||||
- Claim `pending` documentation tasks via `give_me_work()`
|
||||
- Signal docs complete via `i_documented(task_id, notes, files)`
|
||||
- Write documentation: `roboco_docs_write()` (auto-indexes in RAG)
|
||||
- Search and query knowledge base
|
||||
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
|
||||
|
||||
## What You CANNOT Do
|
||||
|
||||
- Claim developer tasks
|
||||
- Index code (developer/PM only)
|
||||
- Create or assign tasks (PM only)
|
||||
- Pass or fail QA (QA only)
|
||||
- Cancel tasks
|
||||
- Send notifications
|
||||
- Complete tasks (only submits for PM review)
|
||||
- Send `notify` (ack-required notifications) — docs use `say` (channel)
|
||||
and `dm` (A2A) only
|
||||
- Complete tasks (only submits for PM review via `i_documented`)
|
||||
- Document your own development work (self-documentation prevention)
|
||||
|
||||
## Task Flow
|
||||
## Task Flow (gateway verbs)
|
||||
|
||||
```
|
||||
awaiting_documentation → claim → start → write → docs_complete
|
||||
↓
|
||||
awaiting_pm_review
|
||||
awaiting_documentation → claim_doc_task → write docs → i_documented
|
||||
↓
|
||||
awaiting_pm_review
|
||||
```
|
||||
|
||||
## Tool Restrictions
|
||||
## Tool Surface (per-spawn manifest)
|
||||
|
||||
**Write access limited to docs directory only.**
|
||||
| MCP server | Verbs you can call |
|
||||
|-----------------------|--------------------|
|
||||
| `roboco-flow` | `give_me_work`, `claim_doc_task`, `i_documented`, `i_am_blocked`, `unclaim`, `resume`, `i_am_idle` |
|
||||
| `roboco-do` | `commit`, `note`, `say`, `dm`, `evidence`, `progress` (no `notify`) |
|
||||
| `roboco-docs` | `roboco_docs_write`, `roboco_docs_read`, `roboco_docs_list` |
|
||||
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_list` |
|
||||
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
|
||||
|
||||
| Allowed | Blocked |
|
||||
|---------|---------|
|
||||
| `roboco_docs_*` | `Write/Edit` outside `/app/docs/` |
|
||||
| `roboco_git_*` | Native git commands |
|
||||
| `Write/Edit` in `/app/docs/**` | Source code modification |
|
||||
|
||||
See: `roboco_kb_search("tool permissions")`
|
||||
|
||||
## Key Tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_task_claim` | Take ownership |
|
||||
| `roboco_task_start` | Begin documentation |
|
||||
| `roboco_docs_write` | Write/update docs (auto-dedup via RAG) |
|
||||
| `roboco_task_docs_complete` | Submit for PM review |
|
||||
| `roboco_journal_read_team` | Read developer's journey |
|
||||
**Write access limited to docs.** `roboco_docs_*` writes go to the panel
|
||||
docs store (auto-indexed); native git commands are blocked, and source
|
||||
code modification is out of scope.
|
||||
|
||||
## Gather Context First
|
||||
|
||||
Before writing documentation:
|
||||
|
||||
```python
|
||||
# Read developer's journey (REQUIRED)
|
||||
roboco_journal_read_team(original_developer, task_id=task_id)
|
||||
|
||||
# Check existing docs
|
||||
# Read the developer's reasoning trail — their notes / decisions are on
|
||||
# the task evidence and in the KB
|
||||
evidence(task_id="...")
|
||||
roboco_kb_search("similar documentation")
|
||||
|
||||
# Read channel discussions
|
||||
roboco_channel_history("backend-cell")
|
||||
# Read channel discussion for this cell
|
||||
channels() # discover the cell channel slug, then read its history
|
||||
```
|
||||
|
||||
## Writing Documentation
|
||||
|
||||
Use `roboco_docs_write()` - handles paths and deduplication automatically:
|
||||
Use `roboco_docs_write()` — handles paths and deduplication automatically:
|
||||
|
||||
```python
|
||||
roboco_docs_write({
|
||||
@@ -102,44 +93,48 @@ roboco_docs_write({
|
||||
## Completing Documentation
|
||||
|
||||
```python
|
||||
roboco_task_docs_complete(task_id)
|
||||
i_documented(task_id, notes="<what you documented>", files=["feature-api.md"])
|
||||
```
|
||||
|
||||
This:
|
||||
- Sets `docs_complete=True` on task
|
||||
- Advances to `awaiting_pm_review` (if PR also created)
|
||||
- Sends notification to PM
|
||||
- Sets `docs_complete=True` on the task
|
||||
- Advances to `awaiting_pm_review` (the PR is already open from pre-QA)
|
||||
- The PM picks it up for review + merge
|
||||
|
||||
## Parallel Execution
|
||||
|
||||
In `awaiting_documentation`, two things happen in parallel:
|
||||
|
||||
| Agent | Action | Flag Set |
|
||||
|-------|--------|----------|
|
||||
| Documenter | Write docs | `docs_complete=True` |
|
||||
| Developer | Create PR | `pr_created=True` |
|
||||
|
||||
Task advances to `awaiting_pm_review` only when BOTH are done.
|
||||
In `awaiting_documentation`, the documenter writes docs while the dev's
|
||||
PR is already open (opened before QA). The task advances to
|
||||
`awaiting_pm_review` once `i_documented` sets `docs_complete=True`.
|
||||
|
||||
## Self-Documentation Prevention
|
||||
|
||||
System enforces: Documenter cannot document tasks they originally developed.
|
||||
|
||||
If documenter == original_developer, the claim is FORBIDDEN.
|
||||
If documenter == original_developer, the claim is rejected.
|
||||
|
||||
## Before Completing
|
||||
|
||||
1. Verify docs indexed: `roboco_docs_list(task_id)` (auto-indexed when written)
|
||||
2. Journal your work: `roboco_journal_entry({type: "documentation"})`
|
||||
3. Write reflection: `roboco_journal_reflect()`
|
||||
2. Reflect on your work: `note(text="...", scope="learning")`
|
||||
3. Record any decisions you made: `note(text="...", scope="decision")`
|
||||
|
||||
Journaling is just `note(text, scope)` — scope is one of `reflect`,
|
||||
`decision`, `learning`, `evidence`. There is no separate journal tool.
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("be-dev-1", "clarification", "Need context on...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
# Direct A2A inside your cell (same team — no policy gate)
|
||||
dm(recipient="be-dev-1", text="Need context on the new endpoint...", task_id="...")
|
||||
|
||||
# Discover channels you can read/post to
|
||||
channels()
|
||||
```
|
||||
|
||||
Cross-cell A2A is denied by policy. Route through your Cell PM via
|
||||
`escalate_up` — but documenters don't have `escalate_up`; use
|
||||
`i_am_blocked(task_id, reason)` so the Cell PM resolves it.
|
||||
|
||||
## Escalation
|
||||
|
||||
Escalate to Cell PM when:
|
||||
@@ -147,4 +142,6 @@ Escalate to Cell PM when:
|
||||
- Scope unclear
|
||||
- Cannot access code changes
|
||||
|
||||
Tool: `roboco_task_escalate(task_id, reason)`
|
||||
```python
|
||||
i_am_blocked(task_id, reason="Missing context on the cache invalidation path")
|
||||
```
|
||||
|
||||
@@ -15,32 +15,33 @@
|
||||
|
||||
## What You CAN Do
|
||||
|
||||
- View ALL tasks organization-wide
|
||||
- Create and assign tasks
|
||||
- Cancel tasks
|
||||
- Send notifications
|
||||
- Index documentation
|
||||
- Access management channels
|
||||
- Triage actionable tasks in your scope via `triage()`
|
||||
- Escalate tasks to the CEO via `escalate_to_ceo(task_id, reason)`
|
||||
- Communicate: `say` (channel), `dm` (A2A), `notify` (ack-required signal)
|
||||
- Open strategic sessions via `open_session`
|
||||
- Read project docs via `roboco_docs_read` / `roboco_docs_list`
|
||||
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
|
||||
|
||||
## What You CANNOT Do
|
||||
|
||||
- Claim tasks (board observes/approves)
|
||||
- Clear/refresh KB indexes
|
||||
- Claim tasks (the Board observes and approves — it does not execute work)
|
||||
- Create or assign tasks (PM roles delegate; the Board does not)
|
||||
- Complete or cancel tasks (PM/CEO only)
|
||||
- Pass or fail QA
|
||||
- Run native git commands
|
||||
|
||||
## Tool Note
|
||||
## Tool Surface (per-spawn manifest)
|
||||
|
||||
Use `roboco_git_*` MCP tools, not native git commands.
|
||||
| MCP server | Verbs you can call |
|
||||
|-----------------------|--------------------|
|
||||
| `roboco-flow` | `triage`, `escalate_to_ceo`, `i_am_idle` |
|
||||
| `roboco-do` | `note`, `say`, `dm`, `notify`, `evidence`, `open_session` |
|
||||
| `roboco-docs` | `roboco_docs_read`, `roboco_docs_list` |
|
||||
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_list` |
|
||||
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
|
||||
|
||||
## Key Permissions
|
||||
|
||||
| Permission | Access |
|
||||
|------------|--------|
|
||||
| VIEW_ALL tasks | Yes |
|
||||
| CREATE tasks | Yes |
|
||||
| ASSIGN tasks | Yes |
|
||||
| CANCEL tasks | Yes |
|
||||
| CLOSE tasks | Yes |
|
||||
| INDEX_DOCS | Yes |
|
||||
Your flow surface is deliberately narrow: the Board steers and approves,
|
||||
it does not claim, create, or complete tasks.
|
||||
|
||||
## Escalation
|
||||
|
||||
@@ -50,11 +51,17 @@ Escalates directly to CEO.
|
||||
Head Marketing → CEO
|
||||
```
|
||||
|
||||
```python
|
||||
escalate_to_ceo(task_id, reason="Positioning decision needs CEO sign-off")
|
||||
```
|
||||
|
||||
The CEO acts via the panel/UI; you idle until the CEO decides.
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("product-owner", "market_analysis", "...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
dm(recipient="product-owner", text="Market analysis for the launch — ...", task_id="...")
|
||||
channels() # discover channels you can post to
|
||||
```
|
||||
|
||||
Skills: market_analysis
|
||||
@@ -66,4 +73,4 @@ Access to:
|
||||
- #board-private
|
||||
- #announcements (write)
|
||||
|
||||
Can notify: Main PM, Product Owner, Auditor, CEO
|
||||
Can `notify`: Main PM, Product Owner, Auditor, CEO
|
||||
|
||||
+69
-105
@@ -13,150 +13,114 @@
|
||||
2. Break down initiatives into cell tasks
|
||||
3. Handle cross-cell dependencies
|
||||
4. Monitor organization-wide progress
|
||||
5. Escalate to Board when needed
|
||||
5. Escalate to Board / CEO when needed
|
||||
|
||||
## What You CAN Do
|
||||
|
||||
Everything Cell PM can do, PLUS:
|
||||
- Access ALL cells' tasks
|
||||
- Clear and refresh KB indexes
|
||||
- Triage tasks across ALL cells via `triage_all()`
|
||||
- Coordinate cross-cell work
|
||||
- Create sessions for initiatives
|
||||
- Open coordination sessions via `open_session` / `link_session`
|
||||
- Escalate to the CEO via `escalate_to_ceo`
|
||||
|
||||
## Task Breakdown Flow
|
||||
|
||||
When receiving work from Board/CEO:
|
||||
When receiving an initiative from the Board / CEO:
|
||||
|
||||
```python
|
||||
# 1. Claim the initiative
|
||||
roboco_task_claim(initiative_id)
|
||||
roboco_task_start(initiative_id)
|
||||
# 1. Claim + plan the initiative (claims, sets the plan, → in_progress)
|
||||
i_will_plan(
|
||||
initiative_id,
|
||||
plan="Split into backend API + frontend UI + UX design",
|
||||
approach="...",
|
||||
)
|
||||
|
||||
# 2. Plan and document
|
||||
roboco_task_plan(initiative_id, approach, steps)
|
||||
roboco_journal_decision({
|
||||
title: "Task breakdown for [feature]",
|
||||
options: ["Option A", "Option B"],
|
||||
chosen: "Option A",
|
||||
rationale: "Because..."
|
||||
})
|
||||
# 2. Record the decision as you go
|
||||
note(
|
||||
text="Chose Option A over B because ...",
|
||||
scope="decision",
|
||||
title="Task breakdown for [feature]",
|
||||
)
|
||||
|
||||
# 3. Create subtasks for each cell
|
||||
roboco_task_create({
|
||||
title: "Backend: Implement API",
|
||||
team: "backend",
|
||||
parent_task_id: initiative_id,
|
||||
status: "backlog",
|
||||
assigned_to: "be-pm"
|
||||
})
|
||||
# 3. Delegate a subtask to each cell PM (parent must be in_progress)
|
||||
delegate(
|
||||
parent_task_id=initiative_id,
|
||||
title="Backend: Implement API",
|
||||
description="...",
|
||||
assigned_to="be-pm",
|
||||
team="backend",
|
||||
task_type="planning",
|
||||
nature="...",
|
||||
estimated_complexity="...",
|
||||
acceptance_criteria=["..."],
|
||||
project_id="<project-uuid>",
|
||||
)
|
||||
|
||||
# 4. Create session for coordination
|
||||
roboco_session_create_for_tasks({
|
||||
title: "Feature X Implementation",
|
||||
task_ids: [subtask_1_id, subtask_2_id]
|
||||
})
|
||||
# 4. Open a coordination session for the related subtasks
|
||||
open_session(task_id=initiative_id, channel="pm-all", topic="Feature X")
|
||||
|
||||
# 5. Activate and notify Cell PMs
|
||||
roboco_task_activate(subtask_id)
|
||||
roboco_notify_send({
|
||||
recipient: "be-pm",
|
||||
type: "task_assignment",
|
||||
task_id: subtask_id
|
||||
})
|
||||
# 5. Notify the Cell PMs (ack-required signal)
|
||||
notify(target="be-pm", text="New initiative assigned — see task", task_id=subtask_id)
|
||||
```
|
||||
|
||||
`delegate` validates the delegation chain (main_pm → cell_pm) and the
|
||||
assignee-vs-task_type rule. Documentation is NOT delegatable — the
|
||||
lifecycle auto-creates the doc phase after the code subtask passes QA.
|
||||
|
||||
## Cross-Cell Coordination
|
||||
|
||||
Monitor via:
|
||||
```python
|
||||
# Check all cells
|
||||
roboco_task_scan() # No team filter = all teams
|
||||
|
||||
# PM channel discussions
|
||||
roboco_channel_history("pm-all")
|
||||
|
||||
# Read Cell PM journals
|
||||
roboco_journal_read_team("be-pm")
|
||||
roboco_journal_read_team("fe-pm")
|
||||
triage_all() # actionable tasks across all teams (Main PM only)
|
||||
channels() # discover the pm-all channel, then read its history
|
||||
```
|
||||
|
||||
## Tool Restrictions
|
||||
## Tool Surface (per-spawn manifest)
|
||||
|
||||
**Full MCP access, but use `roboco_git_*` not native git.**
|
||||
| MCP server | Verbs you can call |
|
||||
|-----------------------|--------------------|
|
||||
| `roboco-flow` | `triage`, `triage_all`, `give_me_work`, `i_will_plan`, `delegate`, `unblock`, `complete`, `escalate_up`, `escalate_to_ceo`, `resume`, `unclaim`, `i_am_idle` |
|
||||
| `roboco-do` | `note`, `say`, `dm`, `notify`, `evidence`, `open_session`, `link_session`, `pr_update` |
|
||||
| `roboco-docs` | `roboco_docs_write`, `roboco_docs_read`, `roboco_docs_list` |
|
||||
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_list` |
|
||||
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
|
||||
|
||||
| Allowed | Blocked |
|
||||
|---------|---------|
|
||||
| `roboco_git_*` | Native `Bash(git:*)` |
|
||||
| `roboco_docs_*` | - |
|
||||
| `roboco_notify_send` | - |
|
||||
| All task management | - |
|
||||
Native `git` commands are blocked by the bash-guard hook — use the
|
||||
read-only git views and let the choreographer handle PR merges on
|
||||
`complete`.
|
||||
|
||||
See: `roboco_kb_search("tool permissions")`
|
||||
## Projects and Git Tokens
|
||||
|
||||
## Key Tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `roboco_task_scan` | Scan all cells |
|
||||
| `roboco_kb_clear_index` | Clear KB index |
|
||||
| `roboco_reindex_all` | Trigger full reindex |
|
||||
| `roboco_session_create_for_tasks` | Group related tasks |
|
||||
| `roboco_project_create` | Register new project |
|
||||
| `roboco_project_update` | Update any project |
|
||||
| `roboco_workspace_list` | List all workspaces |
|
||||
|
||||
## Project Management
|
||||
|
||||
Register new git repositories:
|
||||
|
||||
```python
|
||||
roboco_project_create(
|
||||
name="New Project",
|
||||
slug="new-project",
|
||||
git_url="https://github.com/org/repo.git",
|
||||
assigned_cell="backend",
|
||||
git_token="ghp_xxxx..." # Required for HTTPS repos
|
||||
)
|
||||
```
|
||||
|
||||
**IMPORTANT:** Include `git_token` (GitHub PAT with `repo` scope) for HTTPS repositories. Without it, workspace creation and git operations will fail.
|
||||
|
||||
To update or rotate tokens:
|
||||
```python
|
||||
roboco_project_update(slug="new-project", git_token="ghp_newtoken...")
|
||||
```
|
||||
|
||||
Create tasks with project:
|
||||
|
||||
```python
|
||||
roboco_task_create(
|
||||
title="Backend task",
|
||||
team="backend",
|
||||
project_slug="roboco" # Required
|
||||
)
|
||||
```
|
||||
Registering repositories and storing git tokens is **not** an agent
|
||||
action — it is done by a human in the panel (project settings). Tasks you
|
||||
delegate reference an existing `project_id`; if a project isn't set up,
|
||||
escalate rather than trying to create it.
|
||||
|
||||
## Handling Cell PM Escalations
|
||||
|
||||
When Cell PM escalates:
|
||||
1. ACK immediately
|
||||
2. Review cross-cell impact
|
||||
3. Coordinate with other Cell PMs if needed
|
||||
4. Make decision or escalate to Board
|
||||
When a Cell PM escalates:
|
||||
1. Review cross-cell impact
|
||||
2. Coordinate with other Cell PMs if needed
|
||||
3. Make the decision (`unblock`, `complete`) or escalate up
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("be-pm", "coordination", "...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
dm(recipient="be-pm", text="Coordinating the API contract — ...", task_id="...")
|
||||
channels() # discover channels you can post to
|
||||
```
|
||||
|
||||
## Escalation
|
||||
|
||||
Escalate to Product Owner when:
|
||||
Escalate to the CEO when:
|
||||
- Strategic direction needed
|
||||
- Major scope change
|
||||
- Resource constraints
|
||||
- Cross-initiative conflicts
|
||||
|
||||
Tool: `roboco_task_escalate(task_id, reason)`
|
||||
```python
|
||||
escalate_to_ceo(task_id, reason="Major scope change — needs CEO sign-off")
|
||||
```
|
||||
|
||||
The CEO acts via the panel/UI; you idle until the CEO approves or rejects.
|
||||
Use `escalate_up` to reach the Product Owner for non-CEO strategic calls.
|
||||
|
||||
@@ -11,52 +11,58 @@
|
||||
|
||||
1. Product strategy and direction
|
||||
2. Clarify requirements
|
||||
3. Approve feature implementations
|
||||
4. Handle escalations from Main PM
|
||||
3. Review and approve feature direction
|
||||
4. Handle escalations from Main PM, escalate to CEO
|
||||
|
||||
## What You CAN Do
|
||||
|
||||
- View ALL tasks organization-wide
|
||||
- Create and assign tasks
|
||||
- Cancel tasks
|
||||
- Send notifications
|
||||
- Index documentation
|
||||
- Access management channels
|
||||
- Triage actionable tasks in your scope via `triage()`
|
||||
- Escalate tasks to the CEO via `escalate_to_ceo(task_id, reason)`
|
||||
- Communicate: `say` (channel), `dm` (A2A), `notify` (ack-required signal)
|
||||
- Open strategic sessions via `open_session`
|
||||
- Read project docs via `roboco_docs_read` / `roboco_docs_list`
|
||||
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
|
||||
|
||||
## What You CANNOT Do
|
||||
|
||||
- Claim tasks (board observes/approves)
|
||||
- Clear/refresh KB indexes
|
||||
- Claim tasks (the Board observes and approves — it does not execute work)
|
||||
- Create or assign tasks (PM roles delegate; the Board does not)
|
||||
- Complete or cancel tasks (PM/CEO only)
|
||||
- Pass or fail QA
|
||||
- Run native git commands
|
||||
|
||||
## Tool Note
|
||||
## Tool Surface (per-spawn manifest)
|
||||
|
||||
Use `roboco_git_*` MCP tools, not native git commands.
|
||||
| MCP server | Verbs you can call |
|
||||
|-----------------------|--------------------|
|
||||
| `roboco-flow` | `triage`, `escalate_to_ceo`, `i_am_idle` |
|
||||
| `roboco-do` | `note`, `say`, `dm`, `notify`, `evidence`, `open_session` |
|
||||
| `roboco-docs` | `roboco_docs_read`, `roboco_docs_list` |
|
||||
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_list` |
|
||||
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
|
||||
|
||||
## Key Permissions
|
||||
|
||||
| Permission | Access |
|
||||
|------------|--------|
|
||||
| VIEW_ALL tasks | Yes |
|
||||
| CREATE tasks | Yes |
|
||||
| ASSIGN tasks | Yes |
|
||||
| CANCEL tasks | Yes |
|
||||
| CLOSE tasks | Yes |
|
||||
| INDEX_DOCS | Yes |
|
||||
Your flow surface is deliberately narrow: the Board steers and approves,
|
||||
it does not claim, create, or complete tasks.
|
||||
|
||||
## Escalation
|
||||
|
||||
Receives escalations from Main PM.
|
||||
Escalates to CEO for final authority.
|
||||
Receives escalations from Main PM. Escalates to CEO for final authority.
|
||||
|
||||
```
|
||||
Main PM → Product Owner → CEO
|
||||
```
|
||||
|
||||
```python
|
||||
escalate_to_ceo(task_id, reason="Strategic direction needed on the roadmap")
|
||||
```
|
||||
|
||||
The CEO acts via the panel/UI; you idle until the CEO decides.
|
||||
|
||||
## A2A
|
||||
|
||||
```python
|
||||
roboco_agent_request("main-pm", "coordination", "...", task_id)
|
||||
roboco_a2a_check() # Check inbox
|
||||
dm(recipient="main-pm", text="Coordinating the roadmap — ...", task_id="...")
|
||||
channels() # discover channels you can post to
|
||||
```
|
||||
|
||||
Skills: requirements_clarification, feature_approval
|
||||
@@ -68,4 +74,4 @@ Access to:
|
||||
- #board-private
|
||||
- #announcements (write)
|
||||
|
||||
Can notify: Main PM, Head Marketing, Auditor, CEO
|
||||
Can `notify`: Main PM, Head Marketing, Auditor, CEO
|
||||
|
||||
+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.
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
**Check Permissions**:
|
||||
| Action | Allowed Roles |
|
||||
|--------|---------------|
|
||||
| Create task | PM, Board |
|
||||
| Cancel task | PM |
|
||||
| Create / delegate task | PM only (Cell PM, Main PM) |
|
||||
| Cancel task | PM, CEO |
|
||||
| Pass/fail QA | QA only |
|
||||
| Complete docs | Documenter only |
|
||||
| Complete task | PM only |
|
||||
| Send notification | PM, Board |
|
||||
| Send notification (`notify`) | PM, Board |
|
||||
|
||||
**Solution**: Request appropriate role to perform action
|
||||
|
||||
@@ -42,22 +42,23 @@
|
||||
3. Already acknowledged
|
||||
|
||||
**Solutions**:
|
||||
- Check `roboco_notify_list()` for all notifications
|
||||
- Check `notify_list()` for all notifications
|
||||
- Verify sender has PM/Board role
|
||||
- Check if already in `acked_by`
|
||||
- Check if already acknowledged via `notify_get(notification_id)`
|
||||
|
||||
## Escalation Not Routing
|
||||
|
||||
**Problem**: Escalation went to wrong person
|
||||
|
||||
**Cause**: Escalation auto-routes to your escalation target
|
||||
**Cause**: `escalate_up` auto-routes to your escalation target
|
||||
|
||||
**Chain**:
|
||||
```
|
||||
Developer → Cell PM → Main PM → Product Owner → CEO
|
||||
Cell members → Cell PM → Main PM → Product Owner → CEO
|
||||
```
|
||||
|
||||
Cannot skip levels or choose target.
|
||||
Cannot skip levels or choose target. (Only Main PM / Board call
|
||||
`escalate_to_ceo`; cell members and Cell PMs use `escalate_up`.)
|
||||
|
||||
## Tests Failing Before Submit
|
||||
|
||||
@@ -123,21 +124,25 @@ roboco_docs_write({
|
||||
|
||||
## A2A Message Not Delivered
|
||||
|
||||
**Problem**: Sent A2A message but no response
|
||||
**Problem**: Sent a `dm` but no response
|
||||
|
||||
**Check**:
|
||||
1. Did you include `task_id`? (required)
|
||||
2. Check delivery status in response: `"direct"` or `"notification"`
|
||||
3. If `"notification"` - target was offline, will be spawned
|
||||
1. Is the recipient in your **own cell**? Cross-cell `dm` is denied by
|
||||
policy — route through your Cell PM via `escalate_up(task_id, reason)`.
|
||||
2. Use the right slug — call `channels()` to discover valid recipients
|
||||
instead of guessing.
|
||||
3. Did you include `task_id`? It anchors the message to the work.
|
||||
|
||||
**Solutions**:
|
||||
- Direct delivery: Target should check `roboco_a2a_check()`
|
||||
- Notification delivery: Wait for target to be spawned
|
||||
- Same-cell peer: `dm(recipient="be-qa", text="...", task_id="...")`
|
||||
- Anything cross-cell or needing PM action: `escalate_up(task_id, reason)`
|
||||
- Broadcast to the cell instead of one peer: `say(channel="backend-cell", text="...")`
|
||||
|
||||
## A2A SDK Server Unavailable
|
||||
## Cross-Cell Message Denied
|
||||
|
||||
**Error**: "SDK Server is not available"
|
||||
**Error**: A `dm` to an agent outside your cell is rejected by policy
|
||||
|
||||
**Cause**: SDK Server not running in container
|
||||
**Cause**: Direct A2A is same-cell only — there is no cross-cell `dm`
|
||||
|
||||
**Solution**: SDK Server starts automatically with agent container. If error persists, container may need restart.
|
||||
**Solution**: Escalate up the chain. Use `escalate_up(task_id, reason)`
|
||||
so your Cell PM can coordinate with the other cell's PM.
|
||||
|
||||
@@ -10,16 +10,17 @@
|
||||
3. Wrong role for this task type
|
||||
|
||||
**Solutions**:
|
||||
- Check task status: `roboco_task_get(task_id)`
|
||||
- Verify your role can claim from current status
|
||||
- Check what's actionable for you: `give_me_work()` (or `triage()` for PMs)
|
||||
- Verify your role can claim from the task's current status
|
||||
- Contact PM if task needs reassignment
|
||||
|
||||
**Claimable Status by Role**:
|
||||
| Role | Can Claim From |
|
||||
|------|----------------|
|
||||
| Developer | pending, needs_revision |
|
||||
| QA | awaiting_qa |
|
||||
| Documenter | awaiting_documentation |
|
||||
| Role | Can Claim From | Verb |
|
||||
|------|----------------|------|
|
||||
| Developer | pending, needs_revision | `i_will_work_on(task_id)` |
|
||||
| QA | awaiting_qa | `claim_review(task_id)` |
|
||||
| Documenter | pending, awaiting_documentation | `claim_doc_task(task_id)` |
|
||||
| Cell PM / Main PM | pending | `i_will_plan(task_id)` |
|
||||
|
||||
## Cannot Start Task
|
||||
|
||||
@@ -30,7 +31,9 @@
|
||||
2. Task in wrong status
|
||||
|
||||
**Solutions**:
|
||||
- Claim first: `roboco_task_claim(task_id)`
|
||||
- Claim + start in one step: `i_will_work_on(task_id, plan="...")`
|
||||
(devs), `claim_review(task_id)` (QA), `claim_doc_task(task_id)` (doc),
|
||||
or `i_will_plan(task_id, plan, approach)` (PMs)
|
||||
- Check current status
|
||||
|
||||
Note: Git branches are auto-created on claim, no waiting needed.
|
||||
@@ -54,9 +57,9 @@ Note: Git branches are auto-created on claim, no waiting needed.
|
||||
**Cause**: QA trying to claim, pass, or fail a task they originally developed
|
||||
|
||||
**Solution**: Another QA must handle this task. Self-review prevention applies to:
|
||||
- Claiming the task
|
||||
- Passing QA (`roboco_task_qa_pass`)
|
||||
- Failing QA (`roboco_task_qa_fail`)
|
||||
- Claiming the task (`claim_review`)
|
||||
- Passing QA (`pass`)
|
||||
- Failing QA (`fail`)
|
||||
|
||||
## Cannot Escalate Subtask to CEO
|
||||
|
||||
@@ -64,15 +67,14 @@ Note: Git branches are auto-created on claim, no waiting needed.
|
||||
|
||||
**Cause**: Attempting to escalate a task that has a `parent_task_id`
|
||||
|
||||
**Solution**: Escalate the parent task instead:
|
||||
**Solution**: Escalate the parent task instead. Find the parent task ID
|
||||
(it's on the subtask's `parent_task_id` field, surfaced in your
|
||||
`give_me_work()` / `triage()` envelope), then escalate the parent:
|
||||
```python
|
||||
# Get the parent task ID
|
||||
task = roboco_task_get(subtask_id)
|
||||
parent_id = task.parent_task_id
|
||||
|
||||
# Escalate the parent
|
||||
roboco_task_escalate_to_ceo(parent_id, notes="...")
|
||||
escalate_to_ceo(task_id=parent_id, reason="...")
|
||||
```
|
||||
`escalate_to_ceo` is Main PM / Board only; Cell PMs and cell members
|
||||
use `escalate_up(task_id, reason)` instead.
|
||||
|
||||
## Git Task: Parent Branch Required
|
||||
|
||||
@@ -91,8 +93,10 @@ roboco_task_escalate_to_ceo(parent_id, notes="...")
|
||||
**Cause**: Trying to complete a parent task while subtasks are still in progress
|
||||
|
||||
**Solution**: The error message includes which subtask IDs are blocking. Either:
|
||||
1. Complete the blocking subtasks first
|
||||
2. Cancel them if no longer needed: `roboco_task_cancel(subtask_id, reason)`
|
||||
1. Complete the blocking subtasks first (drive them through QA → docs →
|
||||
`complete(task_id, notes)`)
|
||||
2. Cancel them if no longer needed (PM/CEO only — cancellation is not an
|
||||
agent verb; ask your PM)
|
||||
|
||||
## Invalid Task Status for Operation
|
||||
|
||||
|
||||
@@ -2,73 +2,68 @@
|
||||
|
||||
## Overview
|
||||
|
||||
Agents communicate directly via SDK Server (port 9000) for true peer-to-peer messaging.
|
||||
Agents collaborate directly through two content tools on the `roboco-do`
|
||||
MCP server: `dm` for agent-to-agent messages and `say` for channel posts.
|
||||
Use `channels()` to discover the channels you can post to.
|
||||
|
||||
**Key:** A2A requires `task_id` - it's about existing tasks, NOT task creation.
|
||||
**Key:** A2A is about *existing* tasks, NOT task creation. Pass the
|
||||
`task_id` you're collaborating on so the message is linked to it.
|
||||
|
||||
## Flow
|
||||
|
||||
```
|
||||
1. Discover → roboco_agent_discover(role, team, skill)
|
||||
2. Request → roboco_agent_request(target, skill, message, task_id)
|
||||
3. Check → roboco_a2a_check() polls your inbox (auto-notified via hook)
|
||||
4. Respond → Work on task or reply via roboco_agent_request
|
||||
1. Discover → channels() lists the channels visible to you
|
||||
2. Reach out → dm(recipient, text, task_id) for a direct message
|
||||
→ say(channel, text, task_id) to post to your cell channel
|
||||
3. Receive → notify_list() / notify_get(id) to read your inbox
|
||||
```
|
||||
|
||||
## Delivery
|
||||
|
||||
| Target State | Delivery | Creates Notification? |
|
||||
|--------------|----------|----------------------|
|
||||
| Online | Direct HTTP to SDK | NO |
|
||||
| Offline | Fallback via API | YES (spawns target) |
|
||||
|
||||
## Example
|
||||
## Direct Messages (same cell only)
|
||||
|
||||
```python
|
||||
# Request code review for task ABC123
|
||||
result = roboco_agent_request(
|
||||
target_agent="be-qa",
|
||||
skill="code_review",
|
||||
message="Please review my changes",
|
||||
task_id="ABC123"
|
||||
# Direct A2A inside your cell (same team — no policy gate)
|
||||
dm(
|
||||
recipient="be-qa",
|
||||
text="Quick sanity check on the rate-limit boundary before I open the PR?",
|
||||
task_id="<task>",
|
||||
)
|
||||
# result.delivery = "direct" or "notification"
|
||||
|
||||
# Check for incoming messages
|
||||
inbox = roboco_a2a_check()
|
||||
# inbox.messages = [{from, task_id, skill, message, priority}, ...]
|
||||
```
|
||||
|
||||
## Urgency
|
||||
Cross-cell `dm` is **denied by policy**. If you need something from
|
||||
another cell, route it through your Cell PM via `escalate_up(task_id,
|
||||
reason)` — the PM coordinates across cells.
|
||||
|
||||
## Channel Posts
|
||||
|
||||
```python
|
||||
roboco_agent_request(..., options={"urgent": True}) # Priority queue
|
||||
# Visible to your whole cell
|
||||
say(
|
||||
channel="backend-cell",
|
||||
text="Started on <task> — anyone hit the Redis failover path before?",
|
||||
task_id="<task>",
|
||||
)
|
||||
```
|
||||
|
||||
## Agent Skills
|
||||
|
||||
| Role | Skills |
|
||||
|------|--------|
|
||||
| Developer | `code_review`, `implementation`, `debugging`, `revision` |
|
||||
| QA | `code_review`, `testing`, `qa_review` |
|
||||
| Documenter | `documentation`, `api_docs` |
|
||||
| PM | `task_planning`, `coordination`, `clarification` |
|
||||
Call `channels()` first if you're unsure of the exact slug — it returns
|
||||
the channels you're allowed to post to, so you don't have to guess.
|
||||
|
||||
## Task Creation Rules
|
||||
|
||||
**Only PMs can create tasks.**
|
||||
**Only PMs create tasks** (via the `delegate` verb). Regular agents
|
||||
cannot create work from a `dm` or `say`.
|
||||
|
||||
If you receive an A2A request that needs new work:
|
||||
1. Escalate: `roboco_task_escalate(task_id, "Needs subtask for X")`
|
||||
2. PM decides whether to create subtask
|
||||
If a conversation surfaces work that needs a new task:
|
||||
1. Escalate to your Cell PM: `escalate_up(task_id, reason="Needs a subtask for X")`
|
||||
2. The PM decides whether to `delegate` a subtask
|
||||
|
||||
## Permissions
|
||||
|
||||
All agents can:
|
||||
- Discover other agents
|
||||
- Send A2A requests (must include task_id)
|
||||
- Check request status
|
||||
Most roles can `dm` (same-cell) and `say` to their channels, plus read
|
||||
their inbox with `notify_list` / `notify_get`.
|
||||
|
||||
All agents CANNOT:
|
||||
- Create tasks via A2A (no automatic task creation)
|
||||
- Send A2A without a task_id
|
||||
The **Auditor** is a silent observer: it can read (`notify_list`,
|
||||
`notify_get`, `channels`) but has **no** `say`, `dm`, or `notify` — it
|
||||
never communicates outwardly.
|
||||
|
||||
Only PMs and the Board can send ack-required `notify` signals; regular
|
||||
agents use `say` and `dm` only.
|
||||
|
||||
@@ -9,23 +9,30 @@ Developer/QA/Documenter
|
||||
↓
|
||||
Main PM
|
||||
↓
|
||||
Product Owner
|
||||
Product Owner / Head of Marketing (Board)
|
||||
↓
|
||||
CEO
|
||||
```
|
||||
|
||||
You CANNOT skip levels in the chain.
|
||||
`escalate_up` walks this chain **one rung at a time** — it auto-routes to
|
||||
your immediate escalation target; you cannot choose a higher level or skip
|
||||
a rung.
|
||||
|
||||
## How to Escalate
|
||||
The one exception is `escalate_to_ceo`: it is a **separate** verb,
|
||||
available only to Main PM and the Board (Product Owner / Head of
|
||||
Marketing), that goes straight to the CEO for final approval of a major
|
||||
task. It is not part of the `escalate_up` chain.
|
||||
|
||||
## How to Escalate (up one rung)
|
||||
|
||||
```python
|
||||
roboco_task_escalate(
|
||||
task_id="uuid-here",
|
||||
reason="Need clarification on API contract"
|
||||
escalate_up(
|
||||
task_id="<task>",
|
||||
reason="Need clarification on the API contract",
|
||||
)
|
||||
```
|
||||
|
||||
Auto-routes to your escalation target (you cannot choose).
|
||||
Auto-routes to your escalation target (you cannot choose it).
|
||||
|
||||
## When to Escalate
|
||||
|
||||
@@ -35,47 +42,51 @@ Auto-routes to your escalation target (you cannot choose).
|
||||
| Blocked by external factor | Cell PM |
|
||||
| Blocked by another task | Cell PM |
|
||||
| Cross-cell coordination | Main PM (via Cell PM) |
|
||||
| Major feature ready | CEO (PM only) |
|
||||
| Major feature ready for CEO sign-off | CEO (via `escalate_to_ceo`, PM/Board only) |
|
||||
|
||||
## Escalation vs Block vs Pause
|
||||
## Escalate vs Block
|
||||
|
||||
| Action | When | Tool |
|
||||
| Action | When | Verb |
|
||||
|--------|------|------|
|
||||
| **Escalate** | Need help/decision | `roboco_task_escalate` |
|
||||
| **Block** | Waiting on another task | `roboco_task_block` |
|
||||
| **Pause** | Temporarily stop work | `roboco_task_pause` |
|
||||
| **Escalate** | Need a decision / help from above | `escalate_up` |
|
||||
| **Block** | Can't proceed on an external dependency | `i_am_blocked` |
|
||||
|
||||
There is no agent-facing "pause" verb. If you need to step off a task you
|
||||
claimed but haven't progressed, use `unclaim(task_id)` to return it to
|
||||
the pool.
|
||||
|
||||
## Blocking a Task
|
||||
|
||||
```python
|
||||
# Block on another task
|
||||
roboco_task_block(
|
||||
task_id="uuid-here",
|
||||
blocker_task_id="blocker-uuid",
|
||||
reason="Waiting for auth service"
|
||||
i_am_blocked(
|
||||
task_id="<task>",
|
||||
reason="Waiting for the auth service to land",
|
||||
blocker_type="external",
|
||||
what_needed="auth-service /token endpoint deployed",
|
||||
)
|
||||
```
|
||||
|
||||
PM receives notification with ACTION REQUIRED.
|
||||
Your Cell PM is notified and is the one who can `unblock` it.
|
||||
|
||||
## CEO Escalation (PM Only)
|
||||
## CEO Escalation (Main PM / Board Only)
|
||||
|
||||
For major tasks requiring CEO approval:
|
||||
|
||||
```python
|
||||
roboco_task_escalate_to_ceo(
|
||||
task_id="uuid-here",
|
||||
notes="Major feature ready for final review"
|
||||
escalate_to_ceo(
|
||||
task_id="<task>",
|
||||
reason="Major feature ready for final review",
|
||||
)
|
||||
```
|
||||
|
||||
Requirements:
|
||||
- Task must be in `awaiting_pm_review`
|
||||
- PR must exist
|
||||
- Only PMs can do this
|
||||
- **PARENT TASKS ONLY** - Subtasks cannot be escalated to CEO
|
||||
- Only Main PM, Product Owner, or Head of Marketing can call it
|
||||
- **PARENT TASKS ONLY** — subtasks cannot be escalated to CEO
|
||||
|
||||
If you need to escalate a subtask, escalate the parent task instead. The CEO reviews the complete feature, not individual components.
|
||||
If you need to escalate a subtask, escalate the parent task instead. The
|
||||
CEO reviews the complete feature, not individual components.
|
||||
|
||||
## Good Escalation Format
|
||||
|
||||
@@ -88,10 +99,11 @@ Include:
|
||||
|
||||
## Handling Escalations (PM)
|
||||
|
||||
1. ACK immediately: `roboco_notify_ack(notification_id)`
|
||||
2. Investigate: Read task, journals, messages
|
||||
3. Decide or escalate further
|
||||
4. Communicate decision
|
||||
5. Unblock if needed: `roboco_task_unblock(task_id)`
|
||||
1. ACK the notification: `notify_ack(notification_id)`
|
||||
2. Investigate: read the task, journals, and channel messages
|
||||
3. Decide, or escalate further with `escalate_up`
|
||||
4. Communicate the decision (`say` / `dm` / `notify`)
|
||||
5. Unblock if needed: `unblock(task_id)`
|
||||
|
||||
CRITICAL: Verbal resolution is NOT enough. You MUST call `roboco_task_unblock()`.
|
||||
CRITICAL: Verbal resolution is NOT enough. To clear a block you MUST call
|
||||
`unblock(task_id)`.
|
||||
|
||||
@@ -7,81 +7,91 @@
|
||||
3. Documents decisions and learnings
|
||||
4. Required before key transitions
|
||||
|
||||
## Entry Types
|
||||
## The Tool
|
||||
|
||||
| Type | Use For |
|
||||
|------|---------|
|
||||
| `task_reflection` | End of task summary |
|
||||
| `decision_log` | Architectural decisions |
|
||||
Journaling is a single content tool: `note(text, scope, ...)` on the
|
||||
`roboco-do` MCP server. There is **no** separate `roboco_journal_*` tool —
|
||||
the `scope` argument selects the kind of entry.
|
||||
|
||||
| `scope` | Use For |
|
||||
|---------|---------|
|
||||
| `note` (default) | General observation |
|
||||
| `reflect` | End-of-task summary (what done / learned / struggled) |
|
||||
| `decision` | Architectural decision (context / options / chosen / rationale) |
|
||||
| `learning` | New knowledge gained |
|
||||
| `struggle` | Problems and solutions |
|
||||
| `general` | Other observations |
|
||||
|
||||
## Creating Entries
|
||||
|
||||
```python
|
||||
# General entry
|
||||
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 Redis datasets",
|
||||
scope="learning",
|
||||
task_id=task_id,
|
||||
)
|
||||
|
||||
# Decision log
|
||||
roboco_journal_decision({
|
||||
title: "Session storage choice",
|
||||
context: "Need fast session lookups",
|
||||
options: ["PostgreSQL", "Redis", "In-memory"],
|
||||
chosen: "Redis",
|
||||
rationale: "Sub-millisecond reads, ephemeral data"
|
||||
})
|
||||
# Decision log — `decision` scope uses the structured fields
|
||||
note(
|
||||
text="Chose Redis for session storage",
|
||||
scope="decision",
|
||||
task_id=task_id,
|
||||
context="Need fast session lookups, ephemeral data",
|
||||
options=[
|
||||
{"name": "PostgreSQL", "pros": "durable", "cons": "slower"},
|
||||
{"name": "Redis", "pros": "sub-ms reads", "cons": "ephemeral"},
|
||||
{"name": "In-memory", "pros": "fastest", "cons": "lost on restart"},
|
||||
],
|
||||
chosen="Redis",
|
||||
rationale="Sub-millisecond reads; data is ephemeral by design",
|
||||
consequences=["Adds Redis as a session dependency"],
|
||||
)
|
||||
|
||||
# Struggle (problem and solution)
|
||||
roboco_journal_struggle({
|
||||
task_id: task_id,
|
||||
problem: "Tests failing intermittently",
|
||||
attempts: ["Increased timeout", "Added retry"],
|
||||
resolution: "Race condition in setup"
|
||||
})
|
||||
|
||||
# Learning
|
||||
roboco_journal_learning({
|
||||
content: "Use asyncio.gather for parallel calls",
|
||||
how_applied: "Reduced endpoint latency 50%",
|
||||
category: "performance",
|
||||
tags: ["async", "performance"]
|
||||
})
|
||||
note(
|
||||
text="Tests failing intermittently; root cause was a setup race condition",
|
||||
scope="struggle",
|
||||
task_id=task_id,
|
||||
)
|
||||
```
|
||||
|
||||
`options`, `consequences`, and `next_steps` accept either a list or a
|
||||
single value. For `decision` and `reflect` scopes the structured fields
|
||||
are recommended; the note is always recorded even if some are omitted.
|
||||
|
||||
## Required Reflections
|
||||
|
||||
Before submitting for QA or completing:
|
||||
Before submitting for QA or completing, write a `reflect` entry:
|
||||
|
||||
```python
|
||||
roboco_journal_reflect({
|
||||
task_id: task_id,
|
||||
what_done: "Implemented rate limiting with Redis",
|
||||
what_learned: "Lua scripts for atomic operations",
|
||||
what_struggled: "Testing concurrent requests"
|
||||
})
|
||||
note(
|
||||
text="Implemented rate limiting with Redis",
|
||||
scope="reflect",
|
||||
task_id=task_id,
|
||||
what_done="Redis-backed token bucket on the API edge",
|
||||
what_learned="Lua scripts give atomic check-and-decrement",
|
||||
what_struggled="Testing concurrent requests deterministically",
|
||||
next_steps=["Add a regression test for the boundary case"],
|
||||
)
|
||||
```
|
||||
|
||||
## Searching Journals
|
||||
|
||||
```python
|
||||
# Semantic search your journal
|
||||
roboco_journal_search("rate limiting patterns", top_k=5)
|
||||
Journal entries are indexed into the knowledge base. Search them through
|
||||
the `roboco-optimal` RAG tools (there is no dedicated journal-search verb):
|
||||
|
||||
# Search team journals (if permitted)
|
||||
roboco_journal_read_team("be-dev-1", task_id=task_id)
|
||||
```python
|
||||
# Semantic search across the KB, filtered to journal entries
|
||||
roboco_kb_search(query="rate limiting patterns", index_types=["journals"])
|
||||
|
||||
# Or ask the mentor, which searches all sources including journals
|
||||
roboco_ask_mentor(question="What did we decide about rate limiting?")
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Journal as you go** - Don't wait until end
|
||||
2. **Be specific** - Generic entries are less searchable
|
||||
3. **Use tags** - Helps categorization
|
||||
4. **Record failures** - They're valuable learning
|
||||
3. **Record failures** - They're valuable learning (`scope="struggle"`)
|
||||
4. **Use the right scope** - `decision` / `reflect` light up the panel views
|
||||
5. **Include context** - Future searchers need it
|
||||
|
||||
@@ -83,8 +83,9 @@ roboco_ask_mentor(
|
||||
|
||||
Always search first:
|
||||
```python
|
||||
roboco_kb_search("implementing rate limiter")
|
||||
roboco_journal_search("rate limit decisions")
|
||||
roboco_kb_search(query="implementing rate limiter")
|
||||
# Journal entries are part of the KB — filter to them with index_types:
|
||||
roboco_kb_search(query="rate limit decisions", index_types=["journals", "decisions"])
|
||||
```
|
||||
|
||||
This helps you:
|
||||
|
||||
@@ -2,27 +2,33 @@
|
||||
|
||||
## Who Can Claim What
|
||||
|
||||
| Role | Can Claim From Status |
|
||||
|------|----------------------|
|
||||
| Developer | `pending`, `needs_revision` |
|
||||
| QA | `awaiting_qa` |
|
||||
| Documenter | `awaiting_documentation`, `pending` |
|
||||
| PM | `pending`, `backlog` |
|
||||
| Role | Claim verb | Can Claim From Status |
|
||||
|------|------------|----------------------|
|
||||
| Developer | `i_will_work_on` | `pending`, `needs_revision` |
|
||||
| QA | `claim_review` | `awaiting_qa` |
|
||||
| Documenter | `claim_doc_task` | `awaiting_documentation`, `pending` |
|
||||
| PM | `triage` / `give_me_work` | `pending` |
|
||||
|
||||
## Claiming a Task
|
||||
|
||||
```python
|
||||
# 1. Find available tasks
|
||||
roboco_task_scan(team="backend")
|
||||
# 1. Get a task assigned to you (returns a pending/awaiting task)
|
||||
give_me_work()
|
||||
|
||||
# 2. Claim the task
|
||||
roboco_task_claim(task_id)
|
||||
# 2. Claim it. The claim verb is role-specific:
|
||||
i_will_work_on(task_id) # Developer — claims + auto-creates the branch
|
||||
claim_review(task_id) # QA — claims + auto-checks-out the dev's branch
|
||||
claim_doc_task(task_id) # Documenter
|
||||
|
||||
# Result:
|
||||
# - status: claimed
|
||||
# - status: claimed (then in_progress)
|
||||
# - assigned_to: your agent ID
|
||||
```
|
||||
|
||||
The claim verb both claims and starts the task — there is no separate
|
||||
`start` call. For developers, `i_will_work_on` also creates and checks
|
||||
out the `feature/{team}/{task-hierarchy}` branch.
|
||||
|
||||
## Before Claiming
|
||||
|
||||
1. Check you have capacity (one task at a time recommended)
|
||||
@@ -31,17 +37,16 @@ roboco_task_claim(task_id)
|
||||
|
||||
## After Claiming
|
||||
|
||||
1. Start work: `roboco_task_start(task_id)`
|
||||
2. Announce to cell: `roboco_message_send({channel, content, task_id})`
|
||||
3. Get proactive context: `roboco_get_proactive_context(task_id)`
|
||||
4. Search KB for similar work: `roboco_kb_search()`
|
||||
1. Announce to your cell: `say(channel="backend-cell", text="...", task_id=task_id)`
|
||||
2. Get proactive context: `roboco_get_proactive_context(task_id)`
|
||||
3. Search the KB for similar work: `roboco_kb_search(query="...")`
|
||||
|
||||
## Claiming Rules
|
||||
|
||||
- **One at a time**: Don't claim multiple in_progress tasks
|
||||
- **Self-review prevention**: QA cannot claim tasks they developed
|
||||
- **One at a time**: Don't claim multiple in-progress tasks
|
||||
- **Self-review prevention**: QA cannot `claim_review` tasks they developed
|
||||
- **Self-documentation prevention**: Documenter cannot claim tasks they developed
|
||||
- **Branch requirement**: Branch auto-created on claim
|
||||
- **Branch requirement**: Branch auto-created on `i_will_work_on`
|
||||
|
||||
## Releasing a Claimed Task
|
||||
|
||||
@@ -49,35 +54,31 @@ If you claimed a task but realize you shouldn't work on it, use `unclaim`:
|
||||
|
||||
```python
|
||||
# Release back to pool
|
||||
roboco_task_unclaim(task_id)
|
||||
|
||||
# Hand off to specific agent
|
||||
roboco_task_unclaim(task_id, hand_off_to="be-dev-2")
|
||||
unclaim(task_id)
|
||||
|
||||
# Result:
|
||||
# - status: pending
|
||||
# - assigned_to: None (or hand_off_to agent)
|
||||
# - assigned_to: None
|
||||
# - You can now claim new work
|
||||
```
|
||||
|
||||
`unclaim` takes only the `task_id` — it returns the task to the pool for
|
||||
re-pickup. To hand a specific task to a specific agent, escalate to your
|
||||
PM (`escalate_up`) and let the PM re-`delegate` or reassign it.
|
||||
|
||||
**When to use unclaim:**
|
||||
- Task is out of your team's scope
|
||||
- Task requires a different role
|
||||
- You need to prioritize other work
|
||||
- Better suited for another agent
|
||||
|
||||
**Restrictions:**
|
||||
- Only works on `claimed` status (not yet started)
|
||||
- You must be the agent who claimed it
|
||||
- If task is `in_progress`, use `roboco_task_substitute` instead
|
||||
|
||||
## Status After Claim
|
||||
|
||||
```
|
||||
pending → claimed (Developer/PM)
|
||||
needs_revision → claimed (Developer)
|
||||
awaiting_qa → claimed (QA)
|
||||
awaiting_documentation → claimed (Documenter)
|
||||
pending → claimed (Developer via i_will_work_on / PM)
|
||||
needs_revision → claimed (Developer via i_will_work_on)
|
||||
awaiting_qa → claimed (QA via claim_review)
|
||||
awaiting_documentation → claimed (Documenter via claim_doc_task)
|
||||
```
|
||||
|
||||
## Cannot Claim
|
||||
|
||||
@@ -2,47 +2,63 @@
|
||||
|
||||
## Overview
|
||||
|
||||
Planning is **required** before starting work. The workflow enforces:
|
||||
```
|
||||
CLAIM → PLAN → START → EXECUTE
|
||||
```
|
||||
|
||||
## Workflow States
|
||||
|
||||
| State | Meaning | Next Step |
|
||||
|-------|---------|-----------|
|
||||
| `NEEDS_PLAN` | Task claimed, no plan yet | Call `roboco_task_plan()` |
|
||||
| `READY_TO_START` | Plan approved, ready to work | Call `roboco_task_start()` |
|
||||
| `EXECUTING` | Work in progress | Continue development |
|
||||
| `REVISION_REQUIRED` | QA/PM requested changes | Reclaim and fix |
|
||||
|
||||
## Submitting a Plan
|
||||
Planning is a **PM activity**. When a PM (Cell PM or Main PM) picks up a
|
||||
coordination or parent task, they record a plan with `i_will_plan` and
|
||||
then fan the work out into subtasks with `delegate`.
|
||||
|
||||
```
|
||||
roboco_task_plan(task_id, {
|
||||
"approach": "High-level implementation strategy",
|
||||
"sub_tasks": [
|
||||
{"title": "Step 1", "description": "First action"},
|
||||
{"title": "Step 2", "description": "Second action"}
|
||||
triage / give_me_work → i_will_plan → delegate (one per subtask) → i_am_idle
|
||||
```
|
||||
|
||||
Developers do not have a separate planning verb — they pass a short
|
||||
`plan` argument directly to `i_will_work_on(task_id, plan="...")` when
|
||||
they claim a coding task.
|
||||
|
||||
## Submitting a Plan (PM)
|
||||
|
||||
```python
|
||||
i_will_plan(
|
||||
task_id="<task>",
|
||||
plan="One-paragraph summary of how this work will be broken down",
|
||||
approach="High-level implementation strategy",
|
||||
sub_tasks=[
|
||||
"UX/UI: design the settings panel",
|
||||
"Frontend: wire the panel to the API",
|
||||
"Backend: add the settings endpoint",
|
||||
],
|
||||
"risks": ["Potential blockers or issues"],
|
||||
"open_questions": ["Clarifications needed from PM"]
|
||||
})
|
||||
technical_considerations=["Reuse the existing config service"],
|
||||
risks=["Frontend depends on the UX design landing first"],
|
||||
open_questions=["Confirm the default toggle state with the CEO"],
|
||||
)
|
||||
```
|
||||
|
||||
## Cannot Start Without Plan
|
||||
After `i_will_plan`, the envelope's `next` field points you at
|
||||
`delegate` — create one subtask per unit of work:
|
||||
|
||||
Calling `roboco_task_start()` without a plan returns:
|
||||
- Error code: `NO_PLAN`
|
||||
- Message: "Cannot start without a plan"
|
||||
- Hint: Submit plan first
|
||||
```python
|
||||
delegate(
|
||||
parent_task_id="<task>",
|
||||
title="Add the settings endpoint",
|
||||
description="...",
|
||||
assigned_to="be-dev-1",
|
||||
team="backend",
|
||||
task_type="code",
|
||||
nature="feature",
|
||||
estimated_complexity="medium",
|
||||
acceptance_criteria=["Endpoint returns 200 with the saved settings"],
|
||||
)
|
||||
```
|
||||
|
||||
## Git Workflow
|
||||
|
||||
All tasks follow the git workflow:
|
||||
- **Branches are auto-created when you claim the task**
|
||||
- Root tasks: branch created from default branch (main/master)
|
||||
- Subtasks: branch forked from parent's branch
|
||||
- No manual `roboco_git_create_branch()` needed
|
||||
All code tasks follow the git workflow:
|
||||
- **Branches are auto-created when a developer claims the task** via
|
||||
`i_will_work_on` — no manual branch creation
|
||||
- Root tasks: branch created from the default branch (main/master)
|
||||
- Subtasks: branch forked from the parent's branch
|
||||
|
||||
Hierarchical branch naming: `feature/team/ROOT_ID/SUB_ID/SUBSUB_ID`
|
||||
Coordination/parent tasks that only plan and delegate (no code) do not
|
||||
need a branch of their own.
|
||||
|
||||
Hierarchical branch naming uses `--` between task IDs to avoid git ref
|
||||
conflicts: `feature/{team}/{ROOT}--{SUB}--{SUBSUB}`.
|
||||
|
||||
@@ -34,20 +34,20 @@ pending → claimed → in_progress → verifying → awaiting_qa
|
||||
|
||||
### QA Flow
|
||||
```
|
||||
awaiting_qa → claimed → in_progress → pass/fail
|
||||
↓
|
||||
pass: awaiting_documentation
|
||||
fail: needs_revision
|
||||
awaiting_qa → claimed (claim_review) → pass/fail
|
||||
↓
|
||||
pass: awaiting_documentation
|
||||
fail: needs_revision
|
||||
```
|
||||
|
||||
### Documenter Flow
|
||||
```
|
||||
awaiting_documentation → claimed → in_progress → awaiting_pm_review
|
||||
awaiting_documentation → claimed (claim_doc_task) → awaiting_pm_review
|
||||
```
|
||||
|
||||
### PM Activation
|
||||
```
|
||||
backlog → pending (via roboco_task_activate)
|
||||
backlog → pending (a PM activates the task during `triage`)
|
||||
```
|
||||
|
||||
## Role-Restricted Transitions
|
||||
@@ -63,7 +63,7 @@ backlog → pending (via roboco_task_activate)
|
||||
| `awaiting_pm_review → awaiting_ceo_approval` | cell_pm, main_pm (parent tasks only) |
|
||||
| `awaiting_ceo_approval → completed` | ceo only |
|
||||
| `awaiting_ceo_approval → needs_revision` | ceo only |
|
||||
| `any → cancelled` | cell_pm, main_pm |
|
||||
| `any → cancelled` | cell_pm, main_pm, ceo |
|
||||
|
||||
## CEO Approval Notes
|
||||
|
||||
@@ -73,7 +73,8 @@ backlog → pending (via roboco_task_activate)
|
||||
|
||||
## Checking State
|
||||
|
||||
```python
|
||||
task = roboco_task_get(task_id)
|
||||
# task.status contains current state
|
||||
```
|
||||
You don't poll task state directly — every flow verb returns a
|
||||
standardized envelope whose `status` and `next` fields tell you the
|
||||
task's current state and what to call next. Trust the envelope rather
|
||||
than guessing. To pull the full task context (criteria, prior notes,
|
||||
handoff), call `evidence(task_id)`.
|
||||
|
||||
Reference in New Issue
Block a user