mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(gateway): Wave 1 pre-gateway parity — sessions, progress, notify inbox
Closes empty-panel complaints (Sessions, Progress) and the i_am_idle notification-inbox deadlock identified in the 2026-05-11 gap analysis. All backend service methods already exist; this is pure MCP-surface widening on top of the existing choreographer + ContentActions. New MCP tools (roboco-do): - progress(task_id, message, percentage) — Progress tab writer - open_session(task_id, channel, topic, ...) — Sessions tab writer (PM+) - link_session(session_id, task_id, ...) — Idempotent task↔session - notify_list(unread_only, pending_ack_only, limit) - notify_get(notification_id) - notify_ack(notification_id) Wired through: - roboco/api/schemas/v2/do.py — six new request schemas with Field constraints (Progress.percentage: ge=0, le=100; OpenSession.topic: max_length=200; etc.) - roboco/api/routes/v2/do.py — six new POST routes, thin dispatchers - roboco/services/gateway/content_actions.py — six new ContentActions methods forwarding to TaskService.add_progress, MessagingService.create_session_for_tasks /link_session_to_task, NotificationDeliveryService.list_for_agent / get_for_ recipient_and_mark_read / acknowledge - roboco/mcp/do_server.py — six new typed tool wrappers + registered in _TOOLS - roboco/services/gateway/role_config.py — receivers (list/get/ack) added to every role except auditor (who gets list/get, no ack). Session verbs to PM-or-up. Progress to dev + doc. - agents/prompts/roles/*.md — verb tables updated for developer / QA / documenter / cell_pm / main_pm. i_am_idle line points to notify_list as the deadlock resolution path. Authorization: - progress: assignee + active status (in_progress / verifying / awaiting_qa / awaiting_documentation) - open_session: cell_pm / main_pm / product_owner / head_marketing / ceo - link_session: caller must own the task - notify_ack: caller must be a recipient (ValueError from service maps to not_authorized envelope) Per-file ignore extended: - roboco/services/gateway/**/*.py = [PLC0415, PLR0913] — same rationale as roboco/mcp/**: typed verb signatures are the agent-facing contract; bundling into dataclasses hides field-level schema the LLM needs at the tool layer. Quality: ruff + mypy clean. 503 unit tests pass on touched surfaces. Spec ref: docs/superpowers/specs/2026-05-11-pre-gateway-parity-design.md
This commit is contained in:
@@ -33,7 +33,10 @@ You merge what your developers submit (leaf PRs into your cell branch via `compl
|
||||
| `say(channel, text)` / `dm(recipient, text)` | Channel post / DM. **Channel slug without `#`. 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`). Inventing a slug ("backend-dev", "backend") returns `Channel not found`. | None. |
|
||||
| `notify(target, text, priority?)` | Send a formal ack-required notification to an agent (`be-dev-1`, `ceo`, etc.). `priority` is one of `normal`/`high`/`urgent` (default `normal`). | None. |
|
||||
| `evidence(task_id)` | Inspect a task's PR + commits + diff. | None. |
|
||||
| `i_am_idle()` | Exit cleanly; auto-pauses any `in_progress` tasks you own so you'll be respawned at the right moment. | None. |
|
||||
| `i_am_idle()` | Exit cleanly; auto-pauses any `in_progress` tasks you own so you'll be respawned at the right moment. Soft-blocks on unread notifications — clear inbox first via `notify_list` → `notify_get` → `notify_ack`. | None. |
|
||||
| `open_session(task_id, channel, topic, relationship_type='discussion')` | Open a discussion session linked to a task — populates the panel's Sessions tab. Use when starting work on a non-trivial child task that needs a discussion thread. `channel` is a valid slug from the channel list. | Caller must be PM-or-up; task must exist. |
|
||||
| `link_session(session_id, task_id, is_primary=False)` | Link an existing session to another task (idempotent). | You must own the task. |
|
||||
| `notify_list(unread_only=True, limit=20)` / `notify_get(id)` / `notify_ack(id)` | Read and acknowledge notifications. | None. |
|
||||
|
||||
## State → Verb (YOUR cell-PM task)
|
||||
|
||||
|
||||
@@ -28,7 +28,11 @@ You write code; you do not coordinate. If you find yourself thinking "let me als
|
||||
| `note(text, scope?)` | Journal entry (`scope ∈ note|decision|reflect|learning|struggle`). | None. |
|
||||
| `say(channel, text)` / `dm(recipient, text, skill?)` | Channel post / direct message. | Channel slug without `#`. |
|
||||
| `evidence(task_id)` | Fetches PR diff, commits, files changed, dev summary. | None. |
|
||||
| `i_am_idle()` | Done for now; soft-blocks if you have unread A2A or @mentions. | No active task locks. |
|
||||
| `i_am_idle()` | Done for now; soft-blocks if you have unread A2A or @mentions. Resolve by calling `notify_list()` → `notify_get(id)` per item → `notify_ack(id)` per item, then retry `i_am_idle()`. | No active task locks. |
|
||||
| `progress(task_id, message, percentage)` | Append a narrative progress entry to the panel's Progress tab. `percentage` is 0..100. Use this in addition to `commit()` — commits are git refs, progress is the human-readable update. | Task assigned to you and in `in_progress`/`verifying`/`awaiting_qa`/`awaiting_documentation`. |
|
||||
| `notify_list(unread_only=True, limit=20)` | Read your notification inbox. | None. |
|
||||
| `notify_get(notification_id)` | Read one notification (also marks it read). | Notification recipient must be you. |
|
||||
| `notify_ack(notification_id)` | Acknowledge a notification. | Notification recipient must be you. |
|
||||
|
||||
## State → Verb
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ You do NOT re-implement the developer's work. You do NOT review or critique the
|
||||
| `note(text, scope?)` | Journal entry. | None. |
|
||||
| `say(channel, text)` / `dm(recipient, text, skill?)` | Channel post / direct message. | Channel slug without `#`. |
|
||||
| `evidence(task_id)` | Re-fetches PR diff and commits if needed. | None. |
|
||||
| `i_am_idle()` | Done for now. | No active doc claim. |
|
||||
| `i_am_idle()` | Done for now. Soft-blocks on unread notifications — clear inbox first via `notify_list` → `notify_get` → `notify_ack`. | No active doc claim. |
|
||||
| `progress(task_id, message, percentage)` | Append a narrative progress entry to the panel's Progress tab (0..100). Use in addition to `commit()`. | Task assigned to you and active. |
|
||||
| `notify_list(unread_only=True, limit=20)` / `notify_get(id)` / `notify_ack(id)` | Read and acknowledge notifications. | None. |
|
||||
|
||||
## State → Verb
|
||||
|
||||
|
||||
@@ -33,7 +33,10 @@ You merge what your Cell PMs submit (cell PRs into your root branch via `complet
|
||||
| `say(channel, text)` / `dm(recipient, text)` | Channel post / DM. **Channel slug without `#`. 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`). Inventing a slug returns `Channel not found`. | None. |
|
||||
| `notify(target, text, priority?)` | Send a formal ack-required notification to an agent (`be-dev-1`, `ceo`, etc.). `priority` is one of `normal`/`high`/`urgent` (default `normal`). | None. |
|
||||
| `evidence(task_id)` | Inspect a task's PR + commits + diff. | None. |
|
||||
| `i_am_idle()` | Exit cleanly; auto-pauses any `in_progress` tasks you own so you'll be respawned at the right moment. | None. |
|
||||
| `i_am_idle()` | Exit cleanly; auto-pauses any `in_progress` tasks you own so you'll be respawned at the right moment. Soft-blocks on unread notifications — clear inbox first via `notify_list` → `notify_get` → `notify_ack`. | None. |
|
||||
| `open_session(task_id, channel, topic, relationship_type='discussion')` | Open a strategic discussion session linked to a root task. Populates the panel's Sessions tab. Use when starting work on a cross-cell feature that needs a top-level thread. | Caller is PM-or-up; task exists. |
|
||||
| `link_session(session_id, task_id, is_primary=False)` | Link an existing session to another task. | You must own the task. |
|
||||
| `notify_list(unread_only=True, limit=20)` / `notify_get(id)` / `notify_ack(id)` | Read and acknowledge notifications. | None. |
|
||||
|
||||
## State → Verb (YOUR root task)
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ A pass without evidence is a betrayal of your role: the entire downstream chain
|
||||
| `note(text, scope?)` | Journal entry. Required: `scope='learning'` before `pass`/`fail`. | None. |
|
||||
| `say(channel, text)` / `dm(recipient, text, skill?)` | Channel post / direct message. | Channel slug without `#`. |
|
||||
| `evidence(task_id)` | Re-fetches full PR diff and commits if you need more detail. | None. |
|
||||
| `i_am_idle()` | Done for now. | No active QA claim. |
|
||||
| `i_am_idle()` | Done for now. Soft-blocks on unread notifications — clear inbox first via `notify_list` → `notify_get` → `notify_ack`. | No active QA claim. |
|
||||
| `notify_list(unread_only=True, limit=20)` / `notify_get(id)` / `notify_ack(id)` | Read and acknowledge notifications addressed to you. | None. |
|
||||
|
||||
## State → Verb
|
||||
|
||||
|
||||
Reference in New Issue
Block a user