docs: reflow hard-wrapped prose to one line per paragraph

Markdown and editors soft-wrap on their own, so the manual ~75-char line
breaks across the docs added nothing but noise. Join wrapped prose, list
items, and paragraphs into single lines across 67 docs — README, CLAUDE.md,
deployment, usage, the RAG knowledge base, and the agent role prompts.
Whitespace-only: code fences, tables, and blockquote alerts are byte-identical
and the change is token-verified (no content altered). Applied with a
deterministic reflow tool (committed separately).

Also lands two doc edits that were awaiting commit: the measured under-load
resource numbers in usage.md and the pr_reviewer additions to the
org-structure RAG doc.
This commit is contained in:
Renn F
2026-06-16 23:18:55 +02:00
parent 640a964b88
commit f48106cbb6
67 changed files with 504 additions and 1593 deletions
+1 -2
View File
@@ -17,8 +17,7 @@ ___
Current Documentation Current Documentation
--------------------- ---------------------
Link to (or name) the current documentation page or section that needs improvement: Link to (or name) the current documentation page or section that needs improvement: [Link it here](https://example.com)
[Link it here](https://example.com)
___ ___
+46 -182
View File
@@ -2,236 +2,100 @@
All notable changes to RoboCo are documented in this file. All notable changes to RoboCo are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.0] - 2026-06-16 ## [0.5.0] - 2026-06-16
### Added ### Added
- **Acceptance-criteria & decomposition guardrails.** Every task's acceptance - **Acceptance-criteria & decomposition guardrails.** Every task's acceptance criteria now carry stable per-criterion ids, and each decomposed subtask records which parent criteria it is responsible for (`covers_parent_criteria`). Two gates build on that linkage: a PM can no longer go idle leaving a parent criterion with no subtask responsible for it (the decomposition floor), and a parent can no longer complete / submit up / escalate to the CEO unless every one of its criteria traces to a child that passed QA on it (the roll-up gate). PMs see live coverage in their briefings (`parent_ac_coverage`, `unclaimed_parent_acs`) after each `delegate`. Safe-by-construction: every gate stays inert until a PM starts declaring coverage, so existing decompositions are never blocked. (Migration 036.)
criteria now carry stable per-criterion ids, and each decomposed subtask - **Per-dev sequenced code queues.** A cell PM now delegates each developer its full queue of code subtasks up front instead of one task at a time. Both cell developers build in parallel, and each works its own queue one task at a time, in order — enforced by a per-lane dispatch barrier, with leaf PRs still merged in sequence into the shared cell branch. The old "two code subtasks per parent" ceiling is removed; the 12-subtask hard cap and a same-title duplicate guard remain.
records which parent criteria it is responsible for (`covers_parent_criteria`). - **Unified Business page.** The Company Goals, Secretary, and Pitches pages are consolidated into one tabbed **Business** page (Goals / Secretary / Pitches), modeled on the Knowledge Base page with deep-linkable `?tab=` URLs. A single sidebar entry replaces four.
Two gates build on that linkage: a PM can no longer go idle leaving a parent
criterion with no subtask responsible for it (the decomposition floor), and a
parent can no longer complete / submit up / escalate to the CEO unless every
one of its criteria traces to a child that passed QA on it (the roll-up gate).
PMs see live coverage in their briefings (`parent_ac_coverage`,
`unclaimed_parent_acs`) after each `delegate`. Safe-by-construction: every gate
stays inert until a PM starts declaring coverage, so existing decompositions
are never blocked. (Migration 036.)
- **Per-dev sequenced code queues.** A cell PM now delegates each developer its
full queue of code subtasks up front instead of one task at a time. Both cell
developers build in parallel, and each works its own queue one task at a time,
in order — enforced by a per-lane dispatch barrier, with leaf PRs still merged
in sequence into the shared cell branch. The old "two code subtasks per parent"
ceiling is removed; the 12-subtask hard cap and a same-title duplicate guard
remain.
- **Unified Business page.** The Company Goals, Secretary, and Pitches pages are
consolidated into one tabbed **Business** page (Goals / Secretary / Pitches),
modeled on the Knowledge Base page with deep-linkable `?tab=` URLs. A single
sidebar entry replaces four.
### Changed ### Changed
- **Company Goals, Secretary, and Pitches brought to the panel's standards.** - **Company Goals, Secretary, and Pitches brought to the panel's standards.** Skeleton loading and offline/error states, structured fields instead of raw JSON dumps, required-note confirmation dialogs for pitch and directive decisions, and markdown rendering in the Secretary chat.
Skeleton loading and offline/error states, structured fields instead of raw
JSON dumps, required-note confirmation dialogs for pitch and directive
decisions, and markdown rendering in the Secretary chat.
### Removed ### Removed
- **The standalone Cockpit page.** Its data duplicated the Dashboard and Metrics; - **The standalone Cockpit page.** Its data duplicated the Dashboard and Metrics; its one unique element — the strategy-engine "needs your attention" signals — was relocated to the Dashboard, served by a new lightweight `GET /api/cockpit/signals` endpoint. The `/cockpit`, `/company-goals`, `/secretary`, and `/pitches` panel routes are all retired (404); the Goals, Secretary, and Pitches views now live under `/business?tab=…`.
its one unique element — the strategy-engine "needs your attention" signals —
was relocated to the Dashboard, served by a new lightweight
`GET /api/cockpit/signals` endpoint. The `/cockpit`, `/company-goals`,
`/secretary`, and `/pitches` panel routes are all retired (404); the Goals,
Secretary, and Pitches views now live under `/business?tab=…`.
### Fixed ### Fixed
- **Agent MCP/SDK servers no longer stall on spawn.** They launch with - **Agent MCP/SDK servers no longer stall on spawn.** They launch with `uv run --no-sync`, so a workspace clone whose lockfile has drifted from the baked image no longer triggers a multi-minute dependency re-sync that left the gateway tools stuck "pending" and the developer respawning in a loop.
`uv run --no-sync`, so a workspace clone whose lockfile has drifted from the - **`open_pr` no longer fails on a missing base branch.** `create_pr` auto-creates and pushes the PR's base branch off the default branch when it is not yet on the remote, instead of returning a GitHub 422.
baked image no longer triggers a multi-minute dependency re-sync that left the - **Admin status overrides restore task ownership.** Forcing a blocked task back to pending / in_progress now restores its pre-block assignee, so an escalated code task no longer re-enters the pool still owned by a PM and is dispatched to that PM as if it were a developer.
gateway tools stuck "pending" and the developer respawning in a loop. - **A developer can idle past its own queued work.** With per-dev queues, a dev whose current leaf has moved to QA now idles cleanly while its later queue items wait their turn (the orchestrator respawns it when the lane clears), instead of looping on the idle guard or claiming the next leaf out of order.
- **`open_pr` no longer fails on a missing base branch.** `create_pr` - **26 verified panel UI bugs** across the dashboard, kanban, task detail, and API layer: consistent priority labels and badge sizing, dark-mode coverage, kanban drag-and-drop that prompts for the required audit note, auto-scroll in the message and mentor-chat views, corrected WebSocket reconnect counting, `PATCH` (not `PUT`) for partial task updates, working "Activate Task" and "Start Revision" actions for backlog and needs-revision tasks (no more dead-end menus), the previously-dead "New / Generate Report" buttons, a duplicate agent id, a "0h ago" timestamp, and more.
auto-creates and pushes the PR's base branch off the default branch when it is
not yet on the remote, instead of returning a GitHub 422.
- **Admin status overrides restore task ownership.** Forcing a blocked task back
to pending / in_progress now restores its pre-block assignee, so an escalated
code task no longer re-enters the pool still owned by a PM and is dispatched to
that PM as if it were a developer.
- **A developer can idle past its own queued work.** With per-dev queues, a dev
whose current leaf has moved to QA now idles cleanly while its later queue
items wait their turn (the orchestrator respawns it when the lane clears),
instead of looping on the idle guard or claiming the next leaf out of order.
- **26 verified panel UI bugs** across the dashboard, kanban, task detail, and
API layer: consistent priority labels and badge sizing, dark-mode coverage,
kanban drag-and-drop that prompts for the required audit note, auto-scroll in
the message and mentor-chat views, corrected WebSocket reconnect counting,
`PATCH` (not `PUT`) for partial task updates, working "Activate Task" and
"Start Revision" actions for backlog and needs-revision tasks (no more
dead-end menus), the previously-dead "New / Generate Report" buttons, a
duplicate agent id, a "0h ago" timestamp, and more.
### Internal ### Internal
- Verb-table generation no longer emits tables for the driver-based roles - Verb-table generation no longer emits tables for the driver-based roles (prompter, secretary), whose real tools live in their SDK drivers rather than the gateway verb surface; and the `_briefing_for` typed stub was aligned with its implementation so the composed choreographer type-checks under full mypy.
(prompter, secretary), whose real tools live in their SDK drivers rather than
the gateway verb surface; and the `_briefing_for` typed stub was aligned with
its implementation so the composed choreographer type-checks under full mypy.
## [0.4.0] - 2026-06-15 ## [0.4.0] - 2026-06-15
### Added ### Added
- **Business Goals — the company charter.** A single CEO-owned charter (north - **Business Goals — the company charter.** A single CEO-owned charter (north star, prioritized objectives, constraints, operating policy) injected compactly into every agent's briefing so all work is goal-aware. `GET /api/company-goals` (any agent) / `PUT` (CEO-only), with a panel editor.
star, prioritized objectives, constraints, operating policy) injected - **Web research for the Board and PMs.** Pluggable `web_search` / `web_fetch` exposed through a `roboco-search` MCP server backed by `/api/research/*`, with Tavily / Brave / Exa adapters and a graceful no-op when no provider is configured. The provider key stays server-side — agent containers never make the external request themselves — and a per-agent daily quota (Redis, fail-open) bounds cost.
compactly into every agent's briefing so all work is goal-aware. - **Pitch → approve → provision.** The Board proposes a product (a "pitch"); on CEO approval the system provisions a GitHub repo per target cell, registers a Project for each (and a Product when multi-cell), and seeds one Main-PM delivery task — reusing the existing Product / coordination-task machinery. Default-off: with no provisioning token configured, approval is refused and nothing is created.
`GET /api/company-goals` (any agent) / `PUT` (CEO-only), with a panel editor. - **Autonomous strategy engine (dormant).** An optional second engine that watches the company against its standing goals and surfaces drift, idle, and long-stranded blocked work to the CEO (notify-only — it never spends, builds, or auto-approves). Off by default; the delivery lifecycle is unchanged.
- **Web research for the Board and PMs.** Pluggable `web_search` / `web_fetch` - **The Secretary — the CEO's chief-of-staff.** A live conversational agent (its own role, distinct from the Prompter) the CEO chats with in the panel. It acts only under the CEO's command: it reads company state and relays dictated messages directly, but high-impact actions — editing the charter, starting / cancelling / overriding tasks, approving a pitch, announcements — are queued and run only after the CEO's explicit confirmation (the gate list). Its authority is HMAC-scoped to the secretary role and routed through the existing enforcement, never a parallel permission model.
exposed through a `roboco-search` MCP server backed by `/api/research/*`, with - **The Cockpit.** A read-only `/cockpit` view answering "is the business winning, what's happening, what needs me" — the charter, delivery counts, 30-day spend vs the budget cap, pending pitches, and the strategy engine's signals. Honestly stamped `basis: proxy` (a proxy until real launches).
Tavily / Brave / Exa adapters and a graceful no-op when no provider is
configured. The provider key stays server-side — agent containers never make
the external request themselves — and a per-agent daily quota (Redis,
fail-open) bounds cost.
- **Pitch → approve → provision.** The Board proposes a product (a "pitch");
on CEO approval the system provisions a GitHub repo per target cell, registers
a Project for each (and a Product when multi-cell), and seeds one Main-PM
delivery task — reusing the existing Product / coordination-task machinery.
Default-off: with no provisioning token configured, approval is refused and
nothing is created.
- **Autonomous strategy engine (dormant).** An optional second engine that
watches the company against its standing goals and surfaces drift, idle, and
long-stranded blocked work to the CEO (notify-only — it never spends, builds,
or auto-approves). Off by default; the delivery lifecycle is unchanged.
- **The Secretary — the CEO's chief-of-staff.** A live conversational agent (its
own role, distinct from the Prompter) the CEO chats with in the panel. It acts
only under the CEO's command: it reads company state and relays dictated
messages directly, but high-impact actions — editing the charter, starting /
cancelling / overriding tasks, approving a pitch, announcements — are queued
and run only after the CEO's explicit confirmation (the gate list). Its
authority is HMAC-scoped to the secretary role and routed through the existing
enforcement, never a parallel permission model.
- **The Cockpit.** A read-only `/cockpit` view answering "is the business
winning, what's happening, what needs me" — the charter, delivery counts,
30-day spend vs the budget cap, pending pitches, and the strategy engine's
signals. Honestly stamped `basis: proxy` (a proxy until real launches).
All of these are additive and opt-in or default-off — an unconfigured deployment All of these are additive and opt-in or default-off — an unconfigured deployment behaves exactly as before.
behaves exactly as before.
## [0.3.0] - 2026-06-15 ## [0.3.0] - 2026-06-15
### Added ### Added
- **In-house RAG engine.** Replaced the piragi/torch retrieval stack with an - **In-house RAG engine.** Replaced the piragi/torch retrieval stack with an in-house pgvector engine (asyncpg), then added **hybrid retrieval** — pgvector cosine fused with Postgres full-text ranking — retiring HyDE, plus an embed-once / concurrent-search pass that cut multi-index query latency.
in-house pgvector engine (asyncpg), then added **hybrid retrieval** - **Self-hosted LLM provider** with dynamic model discovery, so agents can run against a local or self-hosted model endpoint.
pgvector cosine fused with Postgres full-text ranking — retiring HyDE, plus - **Quality gates at the source.** Developers run a fast quality gate at `i_am_done` and the full fast gate (including complexity) at their desk; QA requires a per-acceptance-criterion verdict before passing; cells run two developers in parallel with split-before-claim sizing.
an embed-once / concurrent-search pass that cut multi-index query latency. - **Board redraft loop** — the Board can send a drafted task back to intake for an in-context re-draft before it starts.
- **Self-hosted LLM provider** with dynamic model discovery, so agents can run - **Transcript retention** — a background sweep prunes old agent transcripts, with a panel-tunable retention window.
against a local or self-hosted model endpoint.
- **Quality gates at the source.** Developers run a fast quality gate at
`i_am_done` and the full fast gate (including complexity) at their desk; QA
requires a per-acceptance-criterion verdict before passing; cells run two
developers in parallel with split-before-claim sizing.
- **Board redraft loop** — the Board can send a drafted task back to intake for
an in-context re-draft before it starts.
- **Transcript retention** — a background sweep prunes old agent transcripts,
with a panel-tunable retention window.
- **`tests/` type-gated under mypy** — the whole test suite now type-checks in CI. - **`tests/` type-gated under mypy** — the whole test suite now type-checks in CI.
### Fixed ### Fixed
- **PR-divergence respawn-loop meltdown.** Capped the PM respawn loop-gate, - **PR-divergence respawn-loop meltdown.** Capped the PM respawn loop-gate, added CEO god-mode status override, a PR-conflict auto-resolver (rebase → close-superseded / re-merge / escalate), and sequence-ordered sibling merge; the dispatcher can now claim an ownerless `awaiting_pm_review` task without transitioning it.
added CEO god-mode status override, a PR-conflict auto-resolver (rebase → - **Git robustness.** Fall back to a permitted merge method when the repo refuses the requested one, and retarget a PR's base to the default branch when the resolved base is missing on the remote.
close-superseded / re-merge / escalate), and sequence-ordered sibling merge; - **RAG outage.** Migrated the live `chunks_*` tables to the in-house schema (offline-renderable migration), closed engine audit gaps, decoded jsonb metadata returned as a string by asyncpg, and kept the embedding model resident to stop ingest timeouts.
the dispatcher can now claim an ownerless `awaiting_pm_review` task without - **Panel.** Fixed task lifecycle (updates, merge, reassignment, copy), responsive grids + mobile overflow, the status dropdown duplicating the current status, the orchestrator-status reachability signal, and surfaced the CEO "Approve & Start" gate so it can't be missed.
transitioning it. - **Usage attribution.** Agent transcripts are attributed by an orchestrator-assigned session id, fixing zeroed token/cost capture for review-role agents.
- **Git robustness.** Fall back to a permitted merge method when the repo - Composed the prompter role layer for the intake agent; aligned auditor channel permissions; made the app route-registration test robust to FastAPI 0.137; cleared an xenon complexity failure and fixable test warnings.
refuses the requested one, and retarget a PR's base to the default branch
when the resolved base is missing on the remote.
- **RAG outage.** Migrated the live `chunks_*` tables to the in-house schema
(offline-renderable migration), closed engine audit gaps, decoded jsonb
metadata returned as a string by asyncpg, and kept the embedding model
resident to stop ingest timeouts.
- **Panel.** Fixed task lifecycle (updates, merge, reassignment, copy),
responsive grids + mobile overflow, the status dropdown duplicating the
current status, the orchestrator-status reachability signal, and surfaced
the CEO "Approve & Start" gate so it can't be missed.
- **Usage attribution.** Agent transcripts are attributed by an
orchestrator-assigned session id, fixing zeroed token/cost capture for
review-role agents.
- Composed the prompter role layer for the intake agent; aligned auditor
channel permissions; made the app route-registration test robust to FastAPI
0.137; cleared an xenon complexity failure and fixable test warnings.
### Security ### Security
- Documented that WebSocket authentication is REST-only and `/ws/system` is - Documented that WebSocket authentication is REST-only and `/ws/system` is unauthenticated.
unauthenticated.
## [0.2.0] - 2026-06-11 ## [0.2.0] - 2026-06-11
### Added ### Added
- **Provider rate-limit handling.** End-to-end backpressure for LLM-provider - **Provider rate-limit handling.** End-to-end backpressure for LLM-provider 429s: a Redis-backed `RateLimitStateTracker`, a spawn gate that **queues** (never drops) work while a provider is rate-limited, agent parking via `i_am_blocked(reason="rate_limited")`, and a background probe-and-resume loop that auto-revives parked agents when the limit lifts — escalating to the CEO after repeated failed probes. Surfaced live in the panel via a rate-limit banner.
429s: a Redis-backed `RateLimitStateTracker`, a spawn gate that **queues** - **Token usage & cost analytics.** Per-agent-session token capture read from the Claude Code transcript (`/usage/sync`), persisted to spawn-session rows and daily rollups, with provider-aware pricing (Anthropic models priced; local/Ollama models intentionally $0). Visible on the usage dashboard.
(never drops) work while a provider is rate-limited, agent parking via - **`/ws/system` operator WebSocket stream** with a `websocket_bridge` that forwards system events from the event bus to panel clients in real time — the rate-limit lifecycle and live token/cost usage (`USAGE_UPDATE` / `USAGE_SNAPSHOT`), so the dashboard's "Token Usage & Cost" panel updates over the socket and falls back to HTTP polling when it drops.
`i_am_blocked(reason="rate_limited")`, and a background probe-and-resume loop
that auto-revives parked agents when the limit lifts — escalating to the CEO
after repeated failed probes. Surfaced live in the panel via a rate-limit
banner.
- **Token usage & cost analytics.** Per-agent-session token capture read from
the Claude Code transcript (`/usage/sync`), persisted to spawn-session rows
and daily rollups, with provider-aware pricing (Anthropic models priced;
local/Ollama models intentionally $0). Visible on the usage dashboard.
- **`/ws/system` operator WebSocket stream** with a `websocket_bridge` that
forwards system events from the event bus to panel clients in real time — the
rate-limit lifecycle and live token/cost usage (`USAGE_UPDATE` /
`USAGE_SNAPSHOT`), so the dashboard's "Token Usage & Cost" panel updates over
the socket and falls back to HTTP polling when it drops.
### Fixed ### Fixed
- Agent workspaces now install the project's `dev` extra (`uv sync --extra dev`) - Agent workspaces now install the project's `dev` extra (`uv sync --extra dev`) so spawned agents have the full `make quality` toolchain (ruff/mypy/xenon) and can gate their own work — closing the gap that let lint/type/complexity debt merge unchecked.
so spawned agents have the full `make quality` toolchain (ruff/mypy/xenon) and - Token-usage capture: the dashboard previously recorded zeros because nothing populated the per-session counters.
can gate their own work — closing the gap that let lint/type/complexity debt - Panel rate-limit endpoint shape (`/api/system/rate-limits` returns the `{ entries: [...] }` envelope the dashboard expects) and the doubled `/ws/ws/system` WebSocket path.
merge unchecked. - Control-panel logo and all `/public` assets returning 500 — the panel image copied them without chowning to the non-root runtime user.
- Token-usage capture: the dashboard previously recorded zeros because nothing - Provider-aware pricing (Opus corrected to $5/$25 per 1M; non-Anthropic models no longer warn or mis-price).
populated the per-session counters.
- Panel rate-limit endpoint shape (`/api/system/rate-limits` returns the
`{ entries: [...] }` envelope the dashboard expects) and the doubled
`/ws/ws/system` WebSocket path.
- Control-panel logo and all `/public` assets returning 500 — the panel image
copied them without chowning to the non-root runtime user.
- Provider-aware pricing (Opus corrected to $5/$25 per 1M; non-Anthropic models
no longer warn or mis-price).
## [0.1.0] - 2026-06-09 ## [0.1.0] - 2026-06-09
### Added ### Added
- Initial public release of **RoboCo** — an open-source AI agent "company": a - Initial public release of **RoboCo** — an open-source AI agent "company": a virtual organization of 20 AI agents and 1 human CEO that plans, builds, reviews, documents, and ships software.
virtual organization of 20 AI agents and 1 human CEO that plans, builds, - Organizational hierarchy: on-demand Intake, Board (Product Owner, Head of Marketing, Auditor), Main PM, and Backend / Frontend / UX-UI cells.
reviews, documents, and ships software. - **Task Assistant** (the intake Prompter): a live, codebase-aware chat that interviews the CEO and drafts a well-formed, board-ready task — objective, per-cell breakdown, and acceptance criteria — then launches it into the lifecycle (Board review, or straight to the Main PM).
- Organizational hierarchy: on-demand Intake, Board (Product Owner, Head of - Agent gateway (`roboco-flow`, `roboco-do`) backed by the server-side Choreographer; intent-verb tool surface per role.
Marketing, Auditor), Main PM, and Backend / Frontend / UX-UI cells. - Task lifecycle state machine with role-based transitions and git workflow (PR-before-QA, CEO approval for major work).
- **Task Assistant** (the intake Prompter): a live, codebase-aware chat that - A2A protocol, journals, channels/notifications, kanban, and RAG (piragi + pgvector) knowledge base.
interviews the CEO and drafts a well-formed, board-ready task — objective,
per-cell breakdown, and acceptance criteria — then launches it into the
lifecycle (Board review, or straight to the Main PM).
- Agent gateway (`roboco-flow`, `roboco-do`) backed by the server-side
Choreographer; intent-verb tool surface per role.
- Task lifecycle state machine with role-based transitions and git workflow
(PR-before-QA, CEO approval for major work).
- A2A protocol, journals, channels/notifications, kanban, and RAG (piragi +
pgvector) knowledge base.
- Next.js control panel (`panel/`) behind a single nginx entry point. - Next.js control panel (`panel/`) behind a single nginx entry point.
- Multi-agent workspace management with per-project encrypted git tokens. - Multi-agent workspace management with per-project encrypted git tokens.
[0.5.0]: https://github.com/rennf93/roboco/compare/v0.4.0...v0.5.0 [0.5.0]: https://github.com/rennf93/roboco/compare/v0.4.0...v0.5.0 [0.4.0]: https://github.com/rennf93/roboco/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/rennf93/roboco/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/rennf93/roboco/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/rennf93/roboco/releases/tag/v0.1.0
[0.4.0]: https://github.com/rennf93/roboco/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/rennf93/roboco/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/rennf93/roboco/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/rennf93/roboco/releases/tag/v0.1.0
+23 -96
View File
@@ -1,137 +1,66 @@
# RoboCo Contributor License Agreement # RoboCo Contributor License Agreement
Thank you for your interest in contributing to RoboCo (the "Project"), Thank you for your interest in contributing to RoboCo (the "Project"), maintained by Renzo Franceschini (the "Maintainer").
maintained by Renzo Franceschini (the "Maintainer").
This Contributor License Agreement ("Agreement") documents the rights granted This Contributor License Agreement ("Agreement") documents the rights granted by contributors to the Maintainer. It applies to individual contributors; an entity-level version is provided in the [Entity CLA](#entity-cla) section below. By signing this Agreement (see [How to sign](#how-to-sign)), You accept and agree to its terms for Your past, present, and future Contributions to the Project.
by contributors to the Maintainer. It applies to individual contributors; an
entity-level version is provided in the [Entity CLA](#entity-cla) section
below. By signing this Agreement (see [How to sign](#how-to-sign)), You accept
and agree to its terms for Your past, present, and future Contributions to the
Project.
## 1. Definitions ## 1. Definitions
- **"You"** (or **"Your"**) means the individual or legal entity that signs - **"You"** (or **"Your"**) means the individual or legal entity that signs this Agreement.
this Agreement. - **"Contribution"** means any original work of authorship, including any modifications or additions to existing work, that You intentionally submit to the Project in any form, including but not limited to source code, object code, documentation, and configuration. It includes any Contribution You have submitted prior to signing this Agreement.
- **"Contribution"** means any original work of authorship, including any - **"Submit"** means any form of communication sent to the Project, including pull requests, patches, issues, and comments, but excluding communication conspicuously marked "Not a Contribution".
modifications or additions to existing work, that You intentionally submit - **"Maintainer"** means Renzo Franceschini **and the Maintainer's successors and assigns**, including any legal entity that the Maintainer may later form or transfer the Project to.
to the Project in any form, including but not limited to source code, object
code, documentation, and configuration. It includes any Contribution You
have submitted prior to signing this Agreement.
- **"Submit"** means any form of communication sent to the Project, including
pull requests, patches, issues, and comments, but excluding communication
conspicuously marked "Not a Contribution".
- **"Maintainer"** means Renzo Franceschini **and the Maintainer's successors
and assigns**, including any legal entity that the Maintainer may later form
or transfer the Project to.
## 2. Copyright license grant ## 2. Copyright license grant
You retain ownership of the copyright in Your Contribution. Subject to the You retain ownership of the copyright in Your Contribution. Subject to the terms of this Agreement, You hereby grant to the Maintainer and to recipients of software distributed by the Maintainer a **perpetual, worldwide, non-exclusive, royalty-free, irrevocable** copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contribution and such derivative works.
terms of this Agreement, You hereby grant to the Maintainer and to recipients
of software distributed by the Maintainer a **perpetual, worldwide,
non-exclusive, royalty-free, irrevocable** copyright license to reproduce,
prepare derivative works of, publicly display, publicly perform, sublicense,
and distribute Your Contribution and such derivative works.
You further grant the Maintainer the right to **license and re-license Your You further grant the Maintainer the right to **license and re-license Your Contribution under any license terms, including the AGPL-3.0, other open-source licenses, and proprietary or commercial license terms**, and to sublicense these rights through multiple tiers of sublicensees. You acknowledge that this right is what enables the Project to be offered under dual-licensing or commercial terms in the future.
Contribution under any license terms, including the AGPL-3.0, other
open-source licenses, and proprietary or commercial license terms**, and to
sublicense these rights through multiple tiers of sublicensees. You
acknowledge that this right is what enables the Project to be offered under
dual-licensing or commercial terms in the future.
For clarity, this grant is **in addition to** — and does not limit — the For clarity, this grant is **in addition to** — and does not limit — the rights You grant to the public when Your Contribution is distributed as part of the Project under its then-current open-source license (currently AGPL-3.0).
rights You grant to the public when Your Contribution is distributed as part
of the Project under its then-current open-source license (currently
AGPL-3.0).
## 3. Patent license grant ## 3. Patent license grant
Subject to the terms of this Agreement, You grant to the Maintainer and to Subject to the terms of this Agreement, You grant to the Maintainer and to recipients of software distributed by the Maintainer a perpetual, worldwide, non-exclusive, royalty-free, irrevocable (except as stated below) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer Your Contribution, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution alone or by combination of Your Contribution with the Project. If any entity institutes patent litigation alleging that Your Contribution, or the Project to which You have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement terminate.
recipients of software distributed by the Maintainer a perpetual, worldwide,
non-exclusive, royalty-free, irrevocable (except as stated below) patent
license to make, have made, use, offer to sell, sell, import, and otherwise
transfer Your Contribution, where such license applies only to those patent
claims licensable by You that are necessarily infringed by Your Contribution
alone or by combination of Your Contribution with the Project. If any entity
institutes patent litigation alleging that Your Contribution, or the Project
to which You have contributed, constitutes direct or contributory patent
infringement, then any patent licenses granted to that entity under this
Agreement terminate.
## 4. Moral rights ## 4. Moral rights
To the fullest extent permitted by applicable law, You waive, and agree not to To the fullest extent permitted by applicable law, You waive, and agree not to assert against the Maintainer or its licensees, any moral rights, rights of attribution or integrity, or similar rights You may have in Your Contribution that would otherwise restrict the exercise of the rights granted in Sections 2 and 3. Where such rights cannot be waived under applicable law, You agree not to enforce them against the Maintainer, its licensees, or downstream recipients.
assert against the Maintainer or its licensees, any moral rights, rights of
attribution or integrity, or similar rights You may have in Your Contribution
that would otherwise restrict the exercise of the rights granted in Sections 2
and 3. Where such rights cannot be waived under applicable law, You agree not
to enforce them against the Maintainer, its licensees, or downstream
recipients.
## 5. Third-party materials ## 5. Third-party materials
If You wish to submit work that is not Your original creation, You may submit If You wish to submit work that is not Your original creation, You may submit it to the Project separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including related patents, trademarks, and license agreements) of which You are personally aware, and conspicuously marking the work as "Submitted on behalf of a third party: [named here]". Such submissions are not Contributions under this Agreement and are not covered by the grants above.
it to the Project separately from any Contribution, identifying the complete
details of its source and of any license or other restriction (including
related patents, trademarks, and license agreements) of which You are
personally aware, and conspicuously marking the work as
"Submitted on behalf of a third party: [named here]". Such submissions are not
Contributions under this Agreement and are not covered by the grants above.
## 6. Your representations ## 6. Your representations
You represent that: You represent that:
1. Each of Your Contributions is Your original creation, or You have 1. Each of Your Contributions is Your original creation, or You have sufficient rights to grant the licenses in this Agreement.
sufficient rights to grant the licenses in this Agreement. 2. You are legally entitled to grant the above licenses. If Your employer has rights to intellectual property You create, You represent that You have received permission to make the Contributions on behalf of that employer, or that Your employer has waived such rights for Your Contributions.
2. You are legally entitled to grant the above licenses. If Your employer has 3. Your Contribution does not, to Your knowledge, violate any third party's copyrights, trademarks, patents, or other intellectual property rights.
rights to intellectual property You create, You represent that You have 4. You will notify the Maintainer of any facts or circumstances of which You become aware that would make these representations inaccurate.
received permission to make the Contributions on behalf of that employer,
or that Your employer has waived such rights for Your Contributions.
3. Your Contribution does not, to Your knowledge, violate any third party's
copyrights, trademarks, patents, or other intellectual property rights.
4. You will notify the Maintainer of any facts or circumstances of which You
become aware that would make these representations inaccurate.
## 7. Disclaimer ## 7. Disclaimer
Unless required by applicable law or agreed to in writing, You provide Your Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" basis, without warranties or conditions of any kind, either express or implied.
Contributions on an "AS IS" basis, without warranties or conditions of any
kind, either express or implied.
## 8. No obligation ## 8. No obligation
The Maintainer is under no obligation to accept or use any Contribution. The The Maintainer is under no obligation to accept or use any Contribution. The decision to include a Contribution in the Project is at the Maintainer's sole discretion.
decision to include a Contribution in the Project is at the Maintainer's sole
discretion.
## 9. Governing law ## 9. Governing law
This Agreement is governed by and construed in accordance with the laws of This Agreement is governed by and construed in accordance with the laws of **Italy**, without regard to its conflict-of-law provisions. Any dispute arising out of or relating to this Agreement shall be subject to the exclusive jurisdiction of the competent courts of Italy.
**Italy**, without regard to its conflict-of-law provisions. Any dispute
arising out of or relating to this Agreement shall be subject to the exclusive
jurisdiction of the competent courts of Italy.
## 10. Entire agreement ## 10. Entire agreement
This Agreement is the entire agreement between You and the Maintainer This Agreement is the entire agreement between You and the Maintainer concerning Your Contributions and supersedes any prior agreement on that subject. If any provision is held unenforceable, the remaining provisions remain in full force, and the unenforceable provision will be enforced to the maximum extent permitted by law.
concerning Your Contributions and supersedes any prior agreement on that
subject. If any provision is held unenforceable, the remaining provisions
remain in full force, and the unenforceable provision will be enforced to the
maximum extent permitted by law.
--- ---
## Entity CLA ## Entity CLA
If You are signing on behalf of a legal entity (e.g., Your employer), the If You are signing on behalf of a legal entity (e.g., Your employer), the defined term "You" includes that entity and all entities that control, are controlled by, or are under common control with it. The individual signing represents that they are authorized to bind the entity to this Agreement. All other terms above apply unchanged.
defined term "You" includes that entity and all entities that control, are
controlled by, or are under common control with it. The individual signing
represents that they are authorized to bind the entity to this Agreement. All
other terms above apply unchanged.
--- ---
@@ -141,8 +70,6 @@ Signing is automated through the **CLA Assistant** bot:
1. Open a pull request against the Project. 1. Open a pull request against the Project.
2. The bot will comment on your PR with a link to this Agreement. 2. The bot will comment on your PR with a link to this Agreement.
3. Confirm your agreement by posting the exact comment the bot requests 3. Confirm your agreement by posting the exact comment the bot requests (for example: `I have read the CLA Document and I hereby sign the CLA`).
(for example: `I have read the CLA Document and I hereby sign the CLA`).
Your GitHub username and the signing timestamp are recorded so the signature Your GitHub username and the signing timestamp are recorded so the signature can be verified on future contributions. This is a one-time action.
can be verified on future contributions. This is a one-time action.
+21 -73
View File
@@ -4,14 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Licensing ## Licensing
RoboCo is licensed under **AGPL-3.0** (see `LICENSE`). Copyright (c) 2026 RoboCo is licensed under **AGPL-3.0** (see `LICENSE`). Copyright (c) 2026 Renzo Franceschini. Do NOT reintroduce an MIT or other license reference anywhere (README, headers, package metadata) — the project is AGPL.
Renzo Franceschini. Do NOT reintroduce an MIT or other license reference
anywhere (README, headers, package metadata) — the project is AGPL.
Contributions require a signed **Contributor License Agreement** (`CLA.md`), Contributions require a signed **Contributor License Agreement** (`CLA.md`), automated via the CLA Assistant workflow (`.github/workflows/cla.yml`). The CLA preserves the option to dual-license / offer a commercial edition later; keep copyright assignment language intact. See `CONTRIBUTING.md`.
automated via the CLA Assistant workflow (`.github/workflows/cla.yml`). The
CLA preserves the option to dual-license / offer a commercial edition later;
keep copyright assignment language intact. See `CONTRIBUTING.md`.
## Project Overview ## Project Overview
@@ -112,19 +107,14 @@ Each agent gets their own git clone of a project, enabling parallel development
+-- fe-dev-2/ +-- fe-dev-2/
``` ```
Note: the Next.js control panel now lives at `roboco/panel/` inside this Note: the Next.js control panel now lives at `roboco/panel/` inside this repo (no longer a separate `roboco-panel` project or workspace).
repo (no longer a separate `roboco-panel` project or workspace).
**Key Configuration (roboco/config.py):** **Key Configuration (roboco/config.py):**
- `ROBOCO_WORKSPACES_ROOT`: Root directory for workspaces (default: `/data/workspaces`) - `ROBOCO_WORKSPACES_ROOT`: Root directory for workspaces (default: `/data/workspaces`)
- `ROBOCO_WORKSPACE_AUTO_CLONE`: Auto-clone repos on first access (default: `true`) - `ROBOCO_WORKSPACE_AUTO_CLONE`: Auto-clone repos on first access (default: `true`)
- `ROBOCO_WORKSPACE_CLONE_TIMEOUT`: Clone timeout in seconds (default: `300`) - `ROBOCO_WORKSPACE_CLONE_TIMEOUT`: Clone timeout in seconds (default: `300`)
On a Python workspace, `WorkspaceService` runs `uv sync --extra dev` (not plain On a Python workspace, `WorkspaceService` runs `uv sync --extra dev` (not plain `uv sync`) so the clone's `.venv` carries the full gate toolchain (ruff/mypy/xenon/pytest) — the lint/type/complexity tools live in the `dev` **extra**, which plain `uv sync` skips. Without it an agent's `make quality` fails on `ruff: command not found` and the agent can't gate its own work.
`uv sync`) so the clone's `.venv` carries the full gate toolchain
(ruff/mypy/xenon/pytest) — the lint/type/complexity tools live in the `dev`
**extra**, which plain `uv sync` skips. Without it an agent's `make quality`
fails on `ruff: command not found` and the agent can't gate its own work.
## Git Workflow ## Git Workflow
@@ -190,8 +180,7 @@ Git authentication is managed **per-project** through encrypted GitHub PATs:
### Task States ### Task States
The complete task lifecycle is defined in `roboco/foundation/policy/lifecycle.py` The complete task lifecycle is defined in `roboco/foundation/policy/lifecycle.py` (`roboco/enforcement/task_lifecycle.py` is a backwards-compat shim over it):
(`roboco/enforcement/task_lifecycle.py` is a backwards-compat shim over it):
``` ```
backlog -> pending -> claimed -> in_progress -> [blocked|paused] -> verifying backlog -> pending -> claimed -> in_progress -> [blocked|paused] -> verifying
@@ -248,19 +237,13 @@ All status transitions are validated through the enforcement layer. Key restrict
### Git Integration Requirements ### Git Integration Requirements
All tasks follow git workflow. PR is created BEFORE QA review (not after) All tasks follow git workflow. PR is created BEFORE QA review (not after) so QA can review the real PR diff on GitHub and downstream PM/CEO approval chain off a PR that already exists:
so QA can review the real PR diff on GitHub and downstream PM/CEO approval
chain off a PR that already exists:
1. **claimed -> in_progress**: `branch_name` is auto-set on claim (hierarchical branches) 1. **claimed -> in_progress**: `branch_name` is auto-set on claim (hierarchical branches)
2. **verifying -> awaiting_qa** (submit-qa): Requires `self_verified`, `commits`, 2. **verifying -> awaiting_qa** (submit-qa): Requires `self_verified`, `commits`, `pr_number` (PR open), and at least one `progress_updates` entry
`pr_number` (PR open), and at least one `progress_updates` entry 3. **awaiting_qa -> awaiting_documentation** (pass-qa): Requires `pr_number` and substantive QA notes
3. **awaiting_qa -> awaiting_documentation** (pass-qa): Requires `pr_number` and 4. **awaiting_documentation -> awaiting_pm_review**: Requires `docs_complete=True` (PR already exists from step 2 above)
substantive QA notes 5. **awaiting_pm_review -> awaiting_ceo_approval**: Must have `pr_number` set and all subtasks in a terminal state
4. **awaiting_documentation -> awaiting_pm_review**: Requires `docs_complete=True`
(PR already exists from step 2 above)
5. **awaiting_pm_review -> awaiting_ceo_approval**: Must have `pr_number` set
and all subtasks in a terminal state
### CEO Approval Workflow ### CEO Approval Workflow
@@ -308,8 +291,7 @@ commits: list[CommitRef] # All commits made for this task
## Communication Model ## Communication Model
**Communication** = constant stream (always flowing, logged, observed) **Communication** = constant stream (always flowing, logged, observed) **Notifications** = formal signals (require acknowledgment, sent by PMs/Board only)
**Notifications** = formal signals (require acknowledgment, sent by PMs/Board only)
### Channel Structure ### Channel Structure
- Cell channels: `#backend-cell`, `#frontend-cell`, `#uxui-cell` - Cell channels: `#backend-cell`, `#frontend-cell`, `#uxui-cell`
@@ -333,17 +315,9 @@ The Auditor has silent read access to ALL channels.
## Agent Gateway ## Agent Gateway
Agents do not call the API or per-domain MCP tools directly. They go through Agents do not call the API or per-domain MCP tools directly. They go through two thin MCP servers (`roboco-flow`, `roboco-do`) backed by the server-side **Choreographer** in `roboco/services/gateway/`. The Choreographer composes the existing services (TaskService, JournalService, GitService, etc.) into intent-verb sequences. Tracing, claim-locking, evidence assembly, and remediation hints are all centralized there.
two thin MCP servers (`roboco-flow`, `roboco-do`) backed by the server-side
**Choreographer** in `roboco/services/gateway/`. The Choreographer composes
the existing services (TaskService, JournalService, GitService, etc.) into
intent-verb sequences. Tracing, claim-locking, evidence assembly, and
remediation hints are all centralized there.
Each agent gets a **spawn manifest** at `/app/tool-manifest.json` listing Each agent gets a **spawn manifest** at `/app/tool-manifest.json` listing the verbs its role is allowed to call. The orchestrator builds the manifest from `roboco/services/gateway/role_config.py` and mounts it read-only into the agent container.
the verbs its role is allowed to call. The orchestrator builds the
manifest from `roboco/services/gateway/role_config.py` and mounts it
read-only into the agent container.
### Verb surface (canonical source: `lifecycle.intents_for_role`; every role also gets `i_am_idle`) ### Verb surface (canonical source: `lifecycle.intents_for_role`; every role also gets `i_am_idle`)
@@ -361,11 +335,7 @@ read-only into the agent container.
| prompter | (none beyond `i_am_idle` — not a delivery-lifecycle role; intake interviewer, human-only) | | prompter | (none beyond `i_am_idle` — not a delivery-lifecycle role; intake interviewer, human-only) |
| secretary | (none beyond `i_am_idle` — human-only chief-of-staff; reads company state + runs gated CEO directives) | | secretary | (none beyond `i_am_idle` — human-only chief-of-staff; reads company state + runs gated CEO directives) |
Content tools (do_server) — most roles: `commit`, `note`, `say`, `dm`, `evidence`. Content tools (do_server) — most roles: `commit`, `note`, `say`, `dm`, `evidence`. Auditor is restricted to `note` (scope=reflect) + `evidence`. The `pr_reviewer` posts its change-request on the PR itself (no agent comms). The `prompter` (intake) and `secretary` are restricted to `note` + `evidence` — human-only, no `say`/`dm`/`notify`.
Auditor is restricted to `note` (scope=reflect) + `evidence`. The `pr_reviewer`
posts its change-request on the PR itself (no agent comms). The `prompter`
(intake) and `secretary` are restricted to `note` + `evidence` — human-only,
no `say`/`dm`/`notify`.
### MCP servers running per agent container ### MCP servers running per agent container
@@ -381,9 +351,7 @@ Every verb returns a standardized **Envelope**:
- ok: `{status, task_id, next, evidence?, context_briefing}` - ok: `{status, task_id, next, evidence?, context_briefing}`
- error: `{error, message, remediate, missing}` - error: `{error, message, remediate, missing}`
The `next` field tells the agent what to call next; the `remediate` field The `next` field tells the agent what to call next; the `remediate` field on errors tells them exactly how to fix and retry. Agents should not guess state — trust the response.
on errors tells them exactly how to fix and retry. Agents should not guess
state — trust the response.
## Services ## Services
@@ -443,9 +411,7 @@ ROBOCO_OLLAMA_BASE_URL=http://roboco-ollama:11434
### Container Architecture ### Container Architecture
The system runs as Docker Compose services. All Dockerfiles live under The system runs as Docker Compose services. All Dockerfiles live under `docker/` at the project root; every service uses `context: .` plus `dockerfile: docker/<name>.Dockerfile`.
`docker/` at the project root; every service uses `context: .` plus
`dockerfile: docker/<name>.Dockerfile`.
| Service | Purpose | Healthcheck | | Service | Purpose | Healthcheck |
|---------|---------|-------------| |---------|---------|-------------|
@@ -465,41 +431,23 @@ The system runs as Docker Compose services. All Dockerfiles live under
- `/api/*` and `/ws/*``orchestrator:8000` - `/api/*` and `/ws/*``orchestrator:8000`
- everything else → `panel:3000` - everything else → `panel:3000`
This avoids CORS since the browser sees one origin. The Next.js code uses This avoids CORS since the browser sees one origin. The Next.js code uses relative URLs (`/api`, `/ws`) and lets nginx do the dispatch.
relative URLs (`/api`, `/ws`) and lets nginx do the dispatch.
### WebSocket streams ### WebSocket streams
The orchestrator exposes WebSocket endpoints under `/ws` (router in The orchestrator exposes WebSocket endpoints under `/ws` (router in `roboco/api/websocket.py`, `ConnectionManager` + `broadcast_*` helpers):
`roboco/api/websocket.py`, `ConnectionManager` + `broadcast_*` helpers):
| Endpoint | Purpose | | Endpoint | Purpose |
|----------|---------| |----------|---------|
| `/ws/channels/{id}`, `/ws/agents/{id}`, `/ws/sessions/{id}`, `/ws/notifications/{id}` | Per-resource live streams | | `/ws/channels/{id}`, `/ws/agents/{id}`, `/ws/sessions/{id}`, `/ws/notifications/{id}` | Per-resource live streams |
| `/ws/system` | Operator/system-wide stream (no per-agent keying) — the rate-limit lifecycle (`RATE_LIMIT_HIT` / `RATE_LIMIT_LIFTED`) and live usage (`USAGE_SNAPSHOT`, pushed to the usage dashboard) | | `/ws/system` | Operator/system-wide stream (no per-agent keying) — the rate-limit lifecycle (`RATE_LIMIT_HIT` / `RATE_LIMIT_LIFTED`) and live usage (`USAGE_SNAPSHOT`, pushed to the usage dashboard) |
Server-side events reach these sockets through `roboco/api/websocket_bridge.py`, Server-side events reach these sockets through `roboco/api/websocket_bridge.py`, which subscribes to the `StreamEventBus` and forwards each event to the matching connections. To add a new live event: define an `EventType` (dotted value), publish it to the bus, add a `_handle_*` forwarder in `websocket_bridge`, and consume it on the panel via the `useWebSocket("/<endpoint>", …)` hook — do not stand up a parallel endpoint or client stack.
which subscribes to the `StreamEventBus` and forwards each event to the matching
connections. To add a new live event: define an `EventType` (dotted value),
publish it to the bus, add a `_handle_*` forwarder in `websocket_bridge`, and
consume it on the panel via the `useWebSocket("/<endpoint>", …)` hook — do not
stand up a parallel endpoint or client stack.
### Rate limiting & usage ### Rate limiting & usage
- **Provider rate limits** are tracked in Redis (`RateLimitStateTracker`, - **Provider rate limits** are tracked in Redis (`RateLimitStateTracker`, `roboco/services/gateway/`). On a provider 429 an agent calls `i_am_blocked(reason="rate_limited")`; the spawn gate then **queues** (never drops) further work for that provider, and a background probe-and-resume loop in the orchestrator clears the limit and revives parked agents when it lifts.
`roboco/services/gateway/`). On a provider 429 an agent calls - **Token usage** is captured per agent session from the Claude Code transcript via the SDK server's `/usage/sync` (hook → orchestrator finalize → `agent_spawn_sessions``daily_usage_rollups` → dashboard). Cost uses provider-aware pricing in `roboco/billing/pricing.py` (Anthropic priced; local/Ollama intentionally `$0`). The token sweep also publishes `USAGE_SNAPSHOT` to `/ws/system`, so the dashboard's "Token Usage & Cost" panel updates live and falls back to HTTP polling when the stream is down.
`i_am_blocked(reason="rate_limited")`; the spawn gate then **queues** (never
drops) further work for that provider, and a background probe-and-resume loop
in the orchestrator clears the limit and revives parked agents when it lifts.
- **Token usage** is captured per agent session from the Claude Code transcript
via the SDK server's `/usage/sync` (hook → orchestrator finalize →
`agent_spawn_sessions``daily_usage_rollups` → dashboard). Cost uses
provider-aware pricing in `roboco/billing/pricing.py` (Anthropic priced;
local/Ollama intentionally `$0`). The token sweep also publishes
`USAGE_SNAPSHOT` to `/ws/system`, so the dashboard's
"Token Usage & Cost" panel updates live and falls back to HTTP polling when
the stream is down.
### Startup Sequence ### Startup Sequence
+4 -16
View File
@@ -1,32 +1,20 @@
# Code of Conduct # Code of Conduct
RoboCo has adopted the **[Contributor Covenant](https://www.contributor-covenant.org), RoboCo has adopted the **[Contributor Covenant](https://www.contributor-covenant.org), version 2.1** as its Code of Conduct. The full, canonical text is published at:
version 2.1** as its Code of Conduct. The full, canonical text is published at:
> https://www.contributor-covenant.org/version/2/1/code_of_conduct/ > https://www.contributor-covenant.org/version/2/1/code_of_conduct/
## Summary ## Summary
Everyone taking part in the RoboCo community — issues, pull requests, code Everyone taking part in the RoboCo community — issues, pull requests, code review, discussions, and any other project channels — is expected to be respectful, welcoming, and collaborative, and to assume good faith. Conduct that harasses, demeans, intimidates, or excludes others is not acceptable. Project maintainers are responsible for clarifying and enforcing these standards fairly and consistently.
review, discussions, and any other project channels — is expected to be
respectful, welcoming, and collaborative, and to assume good faith. Conduct
that harasses, demeans, intimidates, or excludes others is not acceptable.
Project maintainers are responsible for clarifying and enforcing these
standards fairly and consistently.
## Reporting ## Reporting
To report a concern or a violation, contact the project maintainer privately at To report a concern or a violation, contact the project maintainer privately at **rennf93@gmail.com**. Reports are handled confidentially, reviewed promptly, and acted on fairly. The maintainer will respect the privacy and safety of anyone who reports an incident, and may issue a correction, warning, temporary ban, or permanent ban in proportion to the violation, per the Contributor Covenant's enforcement guidelines.
**rennf93@gmail.com**. Reports are handled confidentially, reviewed promptly,
and acted on fairly. The maintainer will respect the privacy and safety of
anyone who reports an incident, and may issue a correction, warning, temporary
ban, or permanent ban in proportion to the violation, per the Contributor
Covenant's enforcement guidelines.
## Attribution ## Attribution
Adapted from the Contributor Covenant, version 2.1. The full text, enforcement Adapted from the Contributor Covenant, version 2.1. The full text, enforcement guidelines, and FAQ are available at:
guidelines, and FAQ are available at:
- Code of Conduct: https://www.contributor-covenant.org/version/2/1/code_of_conduct/ - Code of Conduct: https://www.contributor-covenant.org/version/2/1/code_of_conduct/
- FAQ: https://www.contributor-covenant.org/faq - FAQ: https://www.contributor-covenant.org/faq
+13 -37
View File
@@ -1,37 +1,22 @@
# Contributing to RoboCo # Contributing to RoboCo
Thanks for your interest in contributing. This document explains the Thanks for your interest in contributing. This document explains the contribution workflow and the licensing terms your contributions are made under.
contribution workflow and the licensing terms your contributions are made
under.
## License of contributions ## License of contributions
RoboCo is licensed under the **GNU Affero General Public License v3.0** RoboCo is licensed under the **GNU Affero General Public License v3.0** (AGPL-3.0). Your contributions are accepted into the project under that license.
(AGPL-3.0). Your contributions are accepted into the project under that
license.
## Contributor License Agreement (CLA) ## Contributor License Agreement (CLA)
Before your first pull request can be merged, you must sign the project's Before your first pull request can be merged, you must sign the project's [Contributor License Agreement](./CLA.md).
[Contributor License Agreement](./CLA.md).
**Why a CLA?** The AGPL keeps the published project open. The CLA grants the **Why a CLA?** The AGPL keeps the published project open. The CLA grants the maintainer the additional rights needed to keep the project's future flexible — for example, to offer a dual-licensed or commercial edition later, or to re-license the codebase if that ever becomes necessary. Without it, the project would be permanently locked to exactly one license, because each contributor would retain sole copyright over their contribution.
maintainer the additional rights needed to keep the project's future flexible
— for example, to offer a dual-licensed or commercial edition later, or to
re-license the codebase if that ever becomes necessary. Without it, the
project would be permanently locked to exactly one license, because each
contributor would retain sole copyright over their contribution.
Signing the CLA does **not** transfer ownership of your work away from you — Signing the CLA does **not** transfer ownership of your work away from you — you keep your copyright. It grants the maintainer (and the maintainer's successors and assigns) a broad license to use, distribute, and re-license your contribution. See [`CLA.md`](./CLA.md) for the exact terms.
you keep your copyright. It grants the maintainer (and the maintainer's
successors and assigns) a broad license to use, distribute, and re-license
your contribution. See [`CLA.md`](./CLA.md) for the exact terms.
### How signing works ### How signing works
The first time you open a pull request, the CLA Assistant bot will comment with The first time you open a pull request, the CLA Assistant bot will comment with a link and ask you to confirm agreement by posting a one-line comment on the PR. This is a one-time action; subsequent PRs are recognized automatically.
a link and ask you to confirm agreement by posting a one-line comment on the
PR. This is a one-time action; subsequent PRs are recognized automatically.
## Development workflow ## Development workflow
@@ -43,27 +28,22 @@ PR. This is a one-time action; subsequent PRs are recognized automatically.
make quality # ruff format check, ruff check, mypy, pytest --cov-fail-under=80 make quality # ruff format check, ruff check, mypy, pytest --cov-fail-under=80
``` ```
For the frontend (`panel/`): For the frontend (`panel/`):
```bash ```bash
pnpm format && pnpm lint && pnpm typecheck && pnpm test pnpm format && pnpm lint && pnpm typecheck && pnpm test
``` ```
4. **Sign your commits.** `master` requires *verified* signatures, so set up 4. **Sign your commits.** `master` requires *verified* signatures, so set up commit signing before you push — see [Signing your commits](#signing-your-commits).
commit signing before you push — see [Signing your commits](#signing-your-commits). 5. Open a pull request with a clear description of the change and its motivation.
5. Open a pull request with a clear description of the change and its
motivation.
## Commit messages ## Commit messages
Keep commits focused and descriptive. Do not include AI-generated attribution Keep commits focused and descriptive. Do not include AI-generated attribution footers or co-author trailers.
footers or co-author trailers.
## Signing your commits ## Signing your commits
`master` is protected by a rule that **every commit must carry a verified `master` is protected by a rule that **every commit must carry a verified signature**. Set this up once and it's automatic from then on; otherwise a maintainer has to bypass the rule to merge your PR.
signature**. Set this up once and it's automatic from then on; otherwise a
maintainer has to bypass the rule to merge your PR.
> This is *cryptographic* signing (`git commit -S`, shown as **Verified** on > This is *cryptographic* signing (`git commit -S`, shown as **Verified** on
> GitHub) — not the `-s` Developer Certificate of Origin *sign-off* trailer. The > GitHub) — not the `-s` Developer Certificate of Origin *sign-off* trailer. The
@@ -77,13 +57,9 @@ git config --global user.signingkey ~/.ssh/id_ed25519.pub # or id_rsa.pub
git config --global commit.gpgsign true git config --global commit.gpgsign true
``` ```
Then add that **same public key** to GitHub a second time as a signing key: Then add that **same public key** to GitHub a second time as a signing key: **Settings → SSH and GPG keys → New SSH key → Key type: _Signing Key_**. (GPG signing also works if you prefer it.)
**Settings → SSH and GPG keys → New SSH key → Key type: _Signing Key_**. (GPG
signing also works if you prefer it.)
Your next commit will be signed; confirm with `git log --show-signature -1`. If Your next commit will be signed; confirm with `git log --show-signature -1`. If you already pushed **unsigned** commits on your PR, re-sign the whole branch and force-push:
you already pushed **unsigned** commits on your PR, re-sign the whole branch and
force-push:
```bash ```bash
git rebase --exec "git commit --amend --no-edit -S" origin/master git rebase --exec "git commit --amend --no-edit -S" origin/master
+20 -68
View File
@@ -28,11 +28,7 @@ AI Agents Company - A virtual organization of 22 AI agents + 1 human CEO, design
</p> </p>
> [!WARNING] > [!WARNING]
> **RoboCo is early-stage, work-in-progress software (v0).** It's under active > **RoboCo is early-stage, work-in-progress software (v0).** It's under active development, runs in a homelab, and *will* have rough edges, breaking changes, and bugs. It is **not production-ready** and the API/database schema are not stable yet. Treat it as a working prototype to explore and build on — please don't expose it to the public internet as-is. Issues and PRs very welcome.
> development, runs in a homelab, and *will* have rough edges, breaking changes,
> and bugs. It is **not production-ready** and the API/database schema are not
> stable yet. Treat it as a working prototype to explore and build on — please
> don't expose it to the public internet as-is. Issues and PRs very welcome.
## Overview ## Overview
@@ -57,22 +53,16 @@ CEO (You, the human)
## How it works ## How it works
You hand a task to the company; it runs through a real You hand a task to the company; it runs through a real *build → review → document → merge* pipeline and comes back to you to approve.
*build → review → document → merge* pipeline and comes back to you to approve.
One full loop, put simply: One full loop, put simply:
1. **You give the Board a task — they review it.** The Product Owner and Head of 1. **You give the Board a task — they review it.** The Product Owner and Head of Marketing turn your ask into requirements and acceptance criteria.
Marketing turn your ask into requirements and acceptance criteria. 2. **You approve — the Main PM starts the work.** A notification asks for your *Approve & Start* decision; approve, and the Main PM breaks it into per-cell subtasks.
2. **You approve — the Main PM starts the work.** A notification asks for your 3. **Each cell's PM delegates, supports, and triages** its developers (UX/UI, Frontend, Backend).
*Approve & Start* decision; approve, and the Main PM breaks it into per-cell
subtasks.
3. **Each cell's PM delegates, supports, and triages** its developers (UX/UI,
Frontend, Backend).
4. **Developers build it, QA verifies and gates it, Documenters keep the books.** 4. **Developers build it, QA verifies and gates it, Documenters keep the books.**
5. **Cell PMs merge their PRs into the Main PM's branch.** 5. **Cell PMs merge their PRs into the Main PM's branch.**
6. **The Main PM opens the final PR and notifies you "It's done!"** — you approve 6. **The Main PM opens the final PR and notifies you "It's done!"** — you approve and merge, or send it back for rework. *(Only you ever merge to `master`.)*
and merge, or send it back for rework. *(Only you ever merge to `master`.)*
**— Full circle —** **— Full circle —**
@@ -113,18 +103,11 @@ roboco/
## Running RoboCo ## Running RoboCo
You need **Docker** + **Docker Compose** and a Claude Code auth directory on You need **Docker** + **Docker Compose** and a Claude Code auth directory on the host (`~/.claude`, mounted into the orchestrator so agents can reach the model). Copy `.env.example` to `.env` and set at least `ROBOCO_ENCRYPTION_KEY` and `ROBOCO_AGENT_AUTH_SECRET` (that file shows how to generate each). However you start it, the whole company is reachable at one origin: **http://localhost:3000**.
the host (`~/.claude`, mounted into the orchestrator so agents can reach the
model). Copy `.env.example` to `.env` and set at least `ROBOCO_ENCRYPTION_KEY`
and `ROBOCO_AGENT_AUTH_SECRET` (that file shows how to generate each). However
you start it, the whole company is reachable at one origin:
**http://localhost:3000**.
### Option 1 — Run the pre-built images (quickest) ### Option 1 — Run the pre-built images (quickest)
Every release publishes all RoboCo images to both the GitHub Container Every release publishes all RoboCo images to both the GitHub Container Registry and Docker Hub, so you can run the full stack without building anything. Use the registry compose:
Registry and Docker Hub, so you can run the full stack without building
anything. Use the registry compose:
```bash ```bash
git clone https://github.com/rennf93/roboco.git && cd roboco git clone https://github.com/rennf93/roboco.git && cd roboco
@@ -140,8 +123,7 @@ ROBOCO_REGISTRY=ghcr.io/rennf93 # or docker.io/renzof93
ROBOCO_VERSION=latest # or a pinned release, e.g. 0.5.0 ROBOCO_VERSION=latest # or a pinned release, e.g. 0.5.0
``` ```
The orchestrator spawns the matching pre-built agent images on demand — no The orchestrator spawns the matching pre-built agent images on demand — no build toolchain or source compile on your host.
build toolchain or source compile on your host.
### Option 2 — Build from source ### Option 2 — Build from source
@@ -155,8 +137,7 @@ docker compose up -d # builds images on first run, then starts ever
### Option 3 — Local development (no full stack) ### Option 3 — Local development (no full stack)
For hacking on the code itself, run only the backing services in Docker and For hacking on the code itself, run only the backing services in Docker and the API on your host:
the API on your host:
```bash ```bash
uv sync uv sync
@@ -238,8 +219,7 @@ Domain routes are mounted under `/api`:
| `/api/journals` | Agent journals/reflections | | `/api/journals` | Agent journals/reflections |
| `/api/orchestrator/status` | Orchestrator / dispatcher status | | `/api/orchestrator/status` | Orchestrator / dispatcher status |
The agent **gateway** verbs are served separately under `/api/v1/flow/{role}/{verb}` The agent **gateway** verbs are served separately under `/api/v1/flow/{role}/{verb}` (intent verbs) and `/api/v1/do` (content tools) — see the [Agent Gateway](CLAUDE.md#agent-gateway).
(intent verbs) and `/api/v1/do` (content tools) — see the [Agent Gateway](CLAUDE.md#agent-gateway).
## Development ## Development
@@ -305,53 +285,25 @@ uv run mypy roboco/
## Security ## Security
> [!IMPORTANT] > [!IMPORTANT]
> **Do not expose RoboCo to the public internet as-is.** It is designed to run > **Do not expose RoboCo to the public internet as-is.** It is designed to run on a trusted private network (homelab / LAN).
> on a trusted private network (homelab / LAN).
**Agent authentication.** Requests identify the caller with `X-Agent-Id` / **Agent authentication.** Requests identify the caller with `X-Agent-Id` / `X-Agent-Role` headers. The orchestrator issues each spawned agent an HMAC token (`X-Agent-Token`, signed with `ROBOCO_AGENT_AUTH_SECRET`) that binds its id, role and team. Token enforcement is gated by `ROBOCO_AGENT_AUTH_REQUIRED`:
`X-Agent-Role` headers. The orchestrator issues each spawned agent an HMAC token
(`X-Agent-Token`, signed with `ROBOCO_AGENT_AUTH_SECRET`) that binds its id, role
and team. Token enforcement is gated by `ROBOCO_AGENT_AUTH_REQUIRED`:
- **`ROBOCO_AGENT_AUTH_REQUIRED` unset/false (default):** *header-trust mode* - **`ROBOCO_AGENT_AUTH_REQUIRED` unset/false (default):** *header-trust mode* the role headers are accepted without a token, so any client that can reach the API may claim any role (including `ceo`). The API logs a warning at startup in this mode. Acceptable only on a trusted network.
the role headers are accepted without a token, so any client that can reach the - **`ROBOCO_AGENT_AUTH_REQUIRED=true`:** every request must carry a valid token; an agent cannot spoof another agent's role. The control panel keeps working because **nginx** — the only trusted hop between the browser and the API — injects the CEO token (`X-Agent-Token`) on `/api` and `/ws`, so the browser never holds the signing secret. Generate that token with `make panel-token` and set it as `ROBOCO_PANEL_AGENT_TOKEN` in `.env` before enabling secure mode.
API may claim any role (including `ceo`). The API logs a warning at startup in
this mode. Acceptable only on a trusted network.
- **`ROBOCO_AGENT_AUTH_REQUIRED=true`:** every request must carry a valid token;
an agent cannot spoof another agent's role. The control panel keeps working
because **nginx** — the only trusted hop between the browser and the API —
injects the CEO token (`X-Agent-Token`) on `/api` and `/ws`, so the browser
never holds the signing secret. Generate that token with `make panel-token`
and set it as `ROBOCO_PANEL_AGENT_TOKEN` in `.env` before enabling secure mode.
**WebSocket streams.** Token enforcement is currently REST-only. The `/ws/*` **WebSocket streams.** Token enforcement is currently REST-only. The `/ws/*` endpoints authenticate by `agent_id` query param at most and do not yet validate `X-Agent-Token`, even in secure mode — nginx injects the token so the panel works, but a direct WebSocket connection that bypasses nginx is not rejected. In particular the operator stream `/ws/system` (rate-limit lifecycle + token-usage snapshots for the dashboard) is unauthenticated. These streams are read-only — no control surface, secrets, or task content — but treat the orchestrator port as trusted-network-only until WebSocket auth lands.
endpoints authenticate by `agent_id` query param at most and do not yet validate
`X-Agent-Token`, even in secure mode — nginx injects the token so the panel
works, but a direct WebSocket connection that bypasses nginx is not rejected. In
particular the operator stream `/ws/system` (rate-limit lifecycle + token-usage
snapshots for the dashboard) is unauthenticated. These streams are read-only —
no control surface, secrets, or task content — but treat the orchestrator port
as trusted-network-only until WebSocket auth lands.
**Secrets** (the Fernet `ROBOCO_ENCRYPTION_KEY`, GitHub PATs) live encrypted in **Secrets** (the Fernet `ROBOCO_ENCRYPTION_KEY`, GitHub PATs) live encrypted in the database and in gitignored env files — never in the repo. Per-project git tokens are Fernet-encrypted at rest and never returned by the API.
the database and in gitignored env files — never in the repo. Per-project git
tokens are Fernet-encrypted at rest and never returned by the API.
## License ## License
Copyright (c) 2026 Renzo Franceschini Copyright (c) 2026 Renzo Franceschini
RoboCo is licensed under the **GNU Affero General Public License v3.0** RoboCo is licensed under the **GNU Affero General Public License v3.0** (AGPL-3.0). See [`LICENSE`](./LICENSE) for the full text.
(AGPL-3.0). See [`LICENSE`](./LICENSE) for the full text.
The AGPL's network-use clause (section 13) means that if you run a modified The AGPL's network-use clause (section 13) means that if you run a modified version of RoboCo as a network service, you must make your modified source available to its users. This keeps the project open while preventing closed, hosted re-distributions.
version of RoboCo as a network service, you must make your modified source
available to its users. This keeps the project open while preventing closed,
hosted re-distributions.
## Contributing ## Contributing
Contributions are welcome. All contributors must sign the Contributor License Contributions are welcome. All contributors must sign the Contributor License Agreement ([`CLA.md`](./CLA.md)) — this is automated on your first pull request. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the workflow and why the CLA exists.
Agreement ([`CLA.md`](./CLA.md)) — this is automated on your first pull
request. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the workflow and why
the CLA exists.
+10 -25
View File
@@ -1,14 +1,10 @@
# Security Policy # Security Policy
RoboCo is licensed under the GNU Affero General Public License v3.0 RoboCo is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). This policy explains which versions receive security fixes and how to report a vulnerability responsibly.
(AGPL-3.0). This policy explains which versions receive security fixes and how
to report a vulnerability responsibly.
## Supported Versions ## Supported Versions
RoboCo is pre-1.0 and ships as a Docker image / GitHub release rather than a RoboCo is pre-1.0 and ships as a Docker image / GitHub release rather than a versioned library. Security fixes are applied to the latest release and the `master` branch only.
versioned library. Security fixes are applied to the latest release and the
`master` branch only.
| Version | Supported | | Version | Supported |
| ------------------ | ------------------ | | ------------------ | ------------------ |
@@ -16,9 +12,7 @@ versioned library. Security fixes are applied to the latest release and the
| Latest release tag | :white_check_mark: | | Latest release tag | :white_check_mark: |
| Older releases | :x: | | Older releases | :x: |
Always run the most recent images — from GHCR (`ghcr.io/rennf93/roboco-*`) or Always run the most recent images — from GHCR (`ghcr.io/rennf93/roboco-*`) or Docker Hub (`renzof93/roboco-*`), tag `latest` — or build from the latest `master`.
Docker Hub (`renzof93/roboco-*`), tag `latest` — or build from the latest
`master`.
## Reporting a Vulnerability ## Reporting a Vulnerability
@@ -26,33 +20,24 @@ Docker Hub (`renzof93/roboco-*`), tag `latest` — or build from the latest
Report privately through one of: Report privately through one of:
1. **GitHub Security Advisories (preferred).** Go to the repository's 1. **GitHub Security Advisories (preferred).** Go to the repository's **Security** tab → **Report a vulnerability**, which opens a private advisory visible only to you and the maintainer.
**Security** tab → **Report a vulnerability**, which opens a private 2. **Email.** Contact the maintainer at **rennf93@gmail.com**. Use a subject line beginning with `[RoboCo Security]`.
advisory visible only to you and the maintainer.
2. **Email.** Contact the maintainer at **rennf93@gmail.com**. Use a subject
line beginning with `[RoboCo Security]`.
Please include, where possible: Please include, where possible:
- A description of the vulnerability and its impact. - A description of the vulnerability and its impact.
- Steps to reproduce, or a proof-of-concept. - Steps to reproduce, or a proof-of-concept.
- The affected subsystem (api, services, gateway, orchestrator, enforcement, - The affected subsystem (api, services, gateway, orchestrator, enforcement, db, agents, mcp, panel) and version / image tag.
db, agents, mcp, panel) and version / image tag.
- Any suggested remediation. - Any suggested remediation.
Particularly relevant to RoboCo's design: issues that could let an agent Particularly relevant to RoboCo's design: issues that could let an agent container exfiltrate a project git token, escape the gateway verb surface, or escalate task-lifecycle permissions are treated as high severity.
container exfiltrate a project git token, escape the gateway verb surface, or
escalate task-lifecycle permissions are treated as high severity.
## Response Expectations ## Response Expectations
This is a maintainer-led open-source project, so timelines are best-effort: This is a maintainer-led open-source project, so timelines are best-effort:
- **Acknowledgement:** within 5 business days of your report. - **Acknowledgement:** within 5 business days of your report.
- **Initial assessment:** within 10 business days, confirming whether the - **Initial assessment:** within 10 business days, confirming whether the issue is accepted and its rough severity.
issue is accepted and its rough severity. - **Fix & disclosure:** coordinated with you. We aim to ship a fix and publish an advisory promptly, crediting you unless you prefer to remain anonymous.
- **Fix & disclosure:** coordinated with you. We aim to ship a fix and publish
an advisory promptly, crediting you unless you prefer to remain anonymous.
Please give us a reasonable window to remediate before any public disclosure. Please give us a reasonable window to remediate before any public disclosure. Thank you for helping keep RoboCo and its users safe.
Thank you for helping keep RoboCo and its users safe.
+2 -17
View File
@@ -95,13 +95,7 @@ The Auditor has no escalation verb — every observation flows through the journ
## Web research (Product Owner & Head of Marketing only) ## Web research (Product Owner & Head of Marketing only)
You have `web_search` and `web_fetch` for grounding product and market calls in You have `web_search` and `web_fetch` for grounding product and market calls in current external evidence — competitors, pricing, positioning, technology trends — that the knowledge base can't answer. Cite the source URL for any claim you act on, and capture key findings with `note(scope='reflect', ...)` so the team retains the source. Calls are quota-limited per day; spend them on decisions that genuinely need fresh external facts. (The Auditor does not have these tools — observe silently.)
current external evidence — competitors, pricing, positioning, technology
trends — that the knowledge base can't answer. Cite the source URL for any
claim you act on, and capture key findings with `note(scope='reflect', ...)` so
the team retains the source. Calls are quota-limited per day; spend them on
decisions that genuinely need fresh external facts. (The Auditor does not have
these tools — observe silently.)
## When the gateway returns an error ## When the gateway returns an error
@@ -109,13 +103,4 @@ Errors include `error`, `message`, `remediate`, `missing`. Read `remediate` —
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, you don't have an `i_am_blocked` verb — `dm(recipient='ceo', text=...)` with the rejection details (PO/HoM only; Auditor uses `note(scope='reflect', text=...)`) so the wedge is captured. The signal indicates a real wedge, not a transient error.
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, you don't have an `i_am_blocked` verb — `dm(recipient='ceo', text=...)`
with the rejection details (PO/HoM only; Auditor uses `note(scope='reflect', text=...)`)
so the wedge is captured. The signal indicates a real wedge, not a transient
error.
+6 -29
View File
@@ -115,14 +115,9 @@ The gateway auto-generates branch names and commit prefixes — your criteria mu
**Write outcome criteria:** **Write outcome criteria:**
`"Feature branch created with name feature/backend/3547f78a-219e-4dcc-..."` — implementation detail; gateway-controlled `"Feature branch created with name feature/backend/3547f78a-219e-4dcc-..."` — implementation detail; gateway-controlled`"Commit message includes task ID prefix [3547f78a]"` — wrong prefix; gateway uses leaf ID ❌ `"PR title is exactly 'Add timestamp comment to README.md'"` — over-prescriptive
`"Commit message includes task ID prefix [3547f78a]"` — wrong prefix; gateway uses leaf ID
`"PR title is exactly 'Add timestamp comment to README.md'"` — over-prescriptive
`"README.md contains a timestamp comment in the form '<!-- timestamp: YYYY-MM-DD -->'"` — verifiable file content `"README.md contains a timestamp comment in the form '<!-- timestamp: YYYY-MM-DD -->'"` — verifiable file content`"A PR is opened and linked to this task (pr_number set)"` — outcome the gateway sets ✅ `"All changes are confined to README.md (no other files touched)"` — scope outcome ✅ `"The commit message subject is at least 20 chars and not a single banned word"` — what the commit_validator enforces
`"A PR is opened and linked to this task (pr_number set)"` — outcome the gateway sets
`"All changes are confined to README.md (no other files touched)"` — scope outcome
`"The commit message subject is at least 20 chars and not a single banned word"` — what the commit_validator enforces
If you must mention task IDs in a criterion, reference the **dev subtask ID** you just delegated (the one in the `delegate(...)` response's `task_id`), not the root — that's what the dev will see in their commit prefix. If you must mention task IDs in a criterion, reference the **dev subtask ID** you just delegated (the one in the `delegate(...)` response's `task_id`), not the root — that's what the dev will see in their commit prefix.
@@ -183,22 +178,12 @@ The PM journal is what makes the cell legible to Main PM and CEO. Skipping entri
- ❌ Calling `complete` on a parent task whose subtasks aren't all terminal. The gateway returns a `tracing_gap` envelope with `missing` containing `subtasks not all terminal`. Wait for the closure dispatcher to bring you back. - ❌ Calling `complete` on a parent task whose subtasks aren't all terminal. The gateway returns a `tracing_gap` envelope with `missing` containing `subtasks not all terminal`. Wait for the closure dispatcher to bring you back.
- ❌ Assigning a subtask to another cell's developer or to Main PM. Subtasks must go to a dev slug in YOUR cell. The gateway rejects cross-cell delegation chains. - ❌ Assigning a subtask to another cell's developer or to Main PM. Subtasks must go to a dev slug in YOUR cell. The gateway rejects cross-cell delegation chains.
- ❌ Calling `i_will_work_on` (that's a developer verb). Yours is `i_will_plan`. - ❌ Calling `i_will_work_on` (that's a developer verb). Yours is `i_will_plan`.
- ❌ Dribbling out one `code` subtask per dev and idling. There is no - ❌ Dribbling out one `code` subtask per dev and idling. There is no two-subtask cap — delegate each dev its full queue of units up front. The orchestrator runs each dev's queue one at a time, in order, so the later items wait their turn on their own; you do not hold them back manually.
two-subtask cap — delegate each dev its full queue of units up front. The - ❌ Re-delegating the *same* unit to the same dev. An exact same-title `code` subtask to a dev that already owns one is rejected as an accidental duplicate — distinct queue items (different titles) are exactly what you want, but don't repeat one.
orchestrator runs each dev's queue one at a time, in order, so the later
items wait their turn on their own; you do not hold them back manually.
- ❌ Re-delegating the *same* unit to the same dev. An exact same-title `code`
subtask to a dev that already owns one is rejected as an accidental
duplicate — distinct queue items (different titles) are exactly what you
want, but don't repeat one.
## Web research ## Web research
You have `web_search` and `web_fetch` for the rare moment decomposition needs a You have `web_search` and `web_fetch` for the rare moment decomposition needs a current external fact — an unfamiliar library's status or an API's constraints — that the knowledge base can't answer. Cite the URL and capture the finding with `note` so your developers inherit the context. Calls are quota-limited per day; use them for genuine unknowns, not routine planning.
current external fact — an unfamiliar library's status or an API's constraints —
that the knowledge base can't answer. Cite the URL and capture the finding with
`note` so your developers inherit the context. Calls are quota-limited per day;
use them for genuine unknowns, not routine planning.
## When the gateway returns an error ## When the gateway returns an error
@@ -206,12 +191,4 @@ Errors include `error`, `message`, `remediate`, `missing`. Read `remediate` —
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, `escalate_up(task_id, reason=...)` with the rejection details — that signal indicates a real wedge, not a transient error. (You have no `i_am_blocked` verb — that is a developer signal; `escalate_up` is yours.)
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, `escalate_up(task_id, reason=...)` with the rejection details — that
signal indicates a real wedge, not a transient error. (You have no
`i_am_blocked` verb — that is a developer signal; `escalate_up` is yours.)
+2 -14
View File
@@ -68,12 +68,7 @@ When you respawn, your task is in some lifecycle status. The next call follows f
11. `i_am_done(task_id="<your-task>", notes="<self-verification summary>")` -> submit for QA against the PR you just opened. Auto-runs the in_progress→verifying→awaiting_qa transitions. Read the envelope: if it returns an error, the `remediate` field tells you which preconditions are missing. 11. `i_am_done(task_id="<your-task>", notes="<self-verification summary>")` -> submit for QA against the PR you just opened. Auto-runs the in_progress→verifying→awaiting_qa transitions. Read the envelope: if it returns an error, the `remediate` field tells you which preconditions are missing.
12. After `i_am_done` succeeds you are finished with this task. `i_am_idle()`. Documenter writes docs; PM merges. You will only be respawned on `needs_revision`. 12. After `i_am_done` succeeds you are finished with this task. `i_am_idle()`. Documenter writes docs; PM merges. You will only be respawned on `needs_revision`.
**Mid-work journal entry required.** The gateway requires at least one **Mid-work journal entry required.** The gateway requires at least one `journal:decision`, `journal:learning`, or `journal:struggle` entry written WHILE the task is `in_progress` — not at the end. The end-of-work `journal:reflect` does NOT satisfy this gate. Write a `decision` after `i_will_work_on` describing your approach; that single entry satisfies the gate. Concrete cadence:
`journal:decision`, `journal:learning`, or `journal:struggle` entry
written WHILE the task is `in_progress` — not at the end. The
end-of-work `journal:reflect` does NOT satisfy this gate. Write a
`decision` after `i_will_work_on` describing your approach; that single
entry satisfies the gate. Concrete cadence:
1. `i_will_work_on(task_id, plan, approach=...)` 1. `i_will_work_on(task_id, plan, approach=...)`
2. `note(scope='decision', text=..., context=..., options=[...], chosen=..., rationale=...)` ← satisfies `journal:during_work>=1` 2. `note(scope='decision', text=..., context=..., options=[...], chosen=..., rationale=...)` ← satisfies `journal:during_work>=1`
@@ -131,11 +126,4 @@ Errors include `error`, `message`, `remediate`, `missing`. **Always read `remedi
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, escalate via `i_am_blocked` with the rejection details — that signal indicates a real wedge, not a transient error.
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, escalate via `i_am_blocked` with the rejection details — that
signal indicates a real wedge, not a transient error.
+1 -10
View File
@@ -96,13 +96,4 @@ Errors include `error`, `message`, `remediate`, `missing`. Read `remediate` —
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, you don't have an `i_am_blocked` verb — `unclaim(task_id)` to release the claim back to pending and `dm(recipient='<cell-pm>', text=...)` with the rejection details so the PM knows it's a real wedge, not a transient error.
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, you don't have an `i_am_blocked` verb — `unclaim(task_id)` to
release the claim back to pending and `dm(recipient='<cell-pm>', text=...)`
with the rejection details so the PM knows it's a real wedge, not a
transient error.
+3 -25
View File
@@ -183,26 +183,11 @@ You are the integration layer between Cells and CEO. Your journal is what tells
- ❌ Calling `i_will_work_on` (that's a developer verb). Yours is `i_will_plan`. - ❌ Calling `i_will_work_on` (that's a developer verb). Yours is `i_will_plan`.
- ❌ On respawn into `claimed`, trying any verb other than `i_will_plan`. The lifecycle requires `claimed → in_progress` before any state-changing operation; the only verb that does that transition for a PM is `i_will_plan`. `delegate`, `complete`, `escalate_*`, `resume`, `unblock` all reject with `invalid_state` on `claimed`. If you cycle through them looking for one that "feels right", you will burn your tool budget without progressing — call `i_will_plan(task_id, plan='resume')` and continue. - ❌ On respawn into `claimed`, trying any verb other than `i_will_plan`. The lifecycle requires `claimed → in_progress` before any state-changing operation; the only verb that does that transition for a PM is `i_will_plan`. `delegate`, `complete`, `escalate_*`, `resume`, `unblock` all reject with `invalid_state` on `claimed`. If you cycle through them looking for one that "feels right", you will burn your tool budget without progressing — call `i_will_plan(task_id, plan='resume')` and continue.
- ❌ Re-decomposing on respawn. If `evidence(root_id)` shows children already exist, do NOT delegate again — that creates duplicates. Either review an `awaiting_pm_review` child or `i_am_idle` until one is ready. - ❌ Re-decomposing on respawn. If `evidence(root_id)` shows children already exist, do NOT delegate again — that creates duplicates. Either review an `awaiting_pm_review` child or `i_am_idle` until one is ready.
- ❌ Concluding "I cannot delegate" after a delegate-rejection that follows - ❌ Concluding "I cannot delegate" after a delegate-rejection that follows a successful delegate. If `delegate(...)` returned `task_id: <id>` earlier in your respawn, that delegation IS LIVE. A subsequent `delegate(...)` returning `invalid_state` citing **spine-cap** (`parent already has a non-terminal task_type='planning' subtask`) or **role-guard** (`task_type='code' is invalid for assignee 'be-pm'`) means you are TRYING TO OVER-DECOMPOSE the parent. The first delegation already covers the work. Verify with `triage()` — if your delegated child is already in the tree, do NOT escalate to product-owner. `i_am_idle()` and let the chain progress; the orchestrator will respawn you when the child needs review.
a successful delegate. If `delegate(...)` returned `task_id: <id>` earlier
in your respawn, that delegation IS LIVE. A subsequent `delegate(...)`
returning `invalid_state` citing **spine-cap** (`parent already has a
non-terminal task_type='planning' subtask`) or **role-guard**
(`task_type='code' is invalid for assignee 'be-pm'`) means you are
TRYING TO OVER-DECOMPOSE the parent. The first delegation already
covers the work. Verify with `triage()` — if your delegated child is
already in the tree, do NOT escalate to product-owner. `i_am_idle()`
and let the chain progress; the orchestrator will respawn you when
the child needs review.
## Web research ## Web research
You have `web_search` and `web_fetch` for the moments planning needs current You have `web_search` and `web_fetch` for the moments planning needs current external facts the knowledge base can't supply — a library's maintenance status, an API's limits, how a competitor approaches a problem. Cite the URL and persist what you learn with `note` so the decision is traceable. Calls are quota-limited per day; reserve them for genuine planning unknowns, not routine coordination.
external facts the knowledge base can't supply — a library's maintenance
status, an API's limits, how a competitor approaches a problem. Cite the URL
and persist what you learn with `note` so the decision is traceable. Calls are
quota-limited per day; reserve them for genuine planning unknowns, not routine
coordination.
## When the gateway returns an error ## When the gateway returns an error
@@ -210,11 +195,4 @@ Errors include `error`, `message`, `remediate`, `missing`. Read `remediate` —
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, `escalate_up(task_id, reason=...)` with the rejection details — that signal indicates a real wedge, not a transient error.
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, `escalate_up(task_id, reason=...)` with the rejection details — that
signal indicates a real wedge, not a transient error.
+4 -10
View File
@@ -80,17 +80,11 @@ A draft card appears for the human with three choices: **Keep chatting**, **Boar
## Re-drafting after board review ## Re-drafting after board review
Sometimes your opening message is not a fresh request but a **revision brief**: it Sometimes your opening message is not a fresh request but a **revision brief**: it contains the current task draft plus the Product Owner / Head of Marketing review ("You are revising an existing task draft with board feedback"). When that happens:
contains the current task draft plus the Product Owner / Head of Marketing review
("You are revising an existing task draft with board feedback"). When that happens:
- Treat the included draft as the starting point — you are improving it, not - Treat the included draft as the starting point — you are improving it, not starting over. Keep what's good; change what the board flagged.
starting over. Keep what's good; change what the board flagged. - Fold the board's points into the spec (naming, scope, acceptance criteria, risks they called out). Where two reviewers conflict, reconcile sensibly and note it.
- Fold the board's points into the spec (naming, scope, acceptance criteria, risks - Briefly say what you changed and why, then **call `propose_draft`** with the revised draft. The human reviews the new draft and confirms it — which updates the same task, not a new one.
they called out). Where two reviewers conflict, reconcile sensibly and note it.
- Briefly say what you changed and why, then **call `propose_draft`** with the
revised draft. The human reviews the new draft and confirms it — which updates
the same task, not a new one.
## Workflow ## Workflow
+1 -10
View File
@@ -100,13 +100,4 @@ Errors include `error`, `message`, `remediate`, `missing`. Read `remediate` —
### Circuit breaker ### Circuit breaker
When the gateway returns `error: circuit_open`, do NOT retry the verb When the gateway returns `error: circuit_open`, do NOT retry the verb immediately. The breaker tracks repeated rejections of the same verb (same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds. Read the `remediate` field — it names what was missing across the last N rejections. Fix that one piece (write the missing journal entry, fill the missing field), then retry the verb ONCE. If the breaker fires again, you don't have an `i_am_blocked` verb — `unclaim(task_id)` to release the claim back to pending and `dm(recipient='<cell-pm>', text=...)` with the rejection details so the PM knows it's a real wedge, not a transient error.
immediately. The breaker tracks repeated rejections of the same verb
(same kind, e.g. `tracing_gap` or `incomplete_input`) within 60 seconds.
Read the `remediate` field — it names what was missing across the last
N rejections. Fix that one piece (write the missing journal entry,
fill the missing field), then retry the verb ONCE. If the breaker fires
again, you don't have an `i_am_blocked` verb — `unclaim(task_id)` to
release the claim back to pending and `dm(recipient='<cell-pm>', text=...)`
with the rejection details so the PM knows it's a real wedge, not a
transient error.
+13 -39
View File
@@ -2,67 +2,41 @@
## Identity ## Identity
You are the **Secretary** — the CEO's conversational chief-of-staff. You exist You are the **Secretary** — the CEO's conversational chief-of-staff. You exist to serve the CEO directly: you read the state of the company, answer the CEO's questions, and carry out the CEO's directives. You talk **only** to the CEO, the way the Intake interviewer talks only to the human — never to other agents on your own initiative.
to serve the CEO directly: you read the state of the company, answer the CEO's
questions, and carry out the CEO's directives. You talk **only** to the CEO,
the way the Intake interviewer talks only to the human — never to other agents
on your own initiative.
You are **not** autonomous. You never originate strategy, never decide what the You are **not** autonomous. You never originate strategy, never decide what the company should do, and never act except on the CEO's instruction. Think of yourself as an extension of the CEO's hands and memory, not a decision-maker. (The company's autonomous watching is a separate, dormant engine; that is not you.)
company should do, and never act except on the CEO's instruction. Think of
yourself as an extension of the CEO's hands and memory, not a decision-maker.
(The company's autonomous watching is a separate, dormant engine; that is not
you.)
## Under the CEO's command, always ## Under the CEO's command, always
Everything you do traces to something the CEO just told you. There is no Everything you do traces to something the CEO just told you. There is no "acting on your own."
"acting on your own."
- **Reading is always free.** You may read the company charter (goals), the - **Reading is always free.** You may read the company charter (goals), the task queue, task details, agent/cell status, and recent activity at any time to inform your answers. Reading never needs confirmation.
task queue, task details, agent/cell status, and recent activity at any time - **Preparing is direct.** When the CEO asks you to draft something — a task spec for their review, a summary, a single message to relay verbatim — you do it directly and show them the result.
to inform your answers. Reading never needs confirmation. - **High-impact actions bounce back for an explicit confirm.** Even when the CEO has told you to do one of these, you restate exactly what you are about to do and wait for a clear "yes" before executing. These are the **gated** actions:
- **Preparing is direct.** When the CEO asks you to draft something — a task
spec for their review, a summary, a single message to relay verbatim — you do
it directly and show them the result.
- **High-impact actions bounce back for an explicit confirm.** Even when the
CEO has told you to do one of these, you restate exactly what you are about to
do and wait for a clear "yes" before executing. These are the **gated**
actions:
- Changing the **company charter** (north star, objectives, constraints, - Changing the **company charter** (north star, objectives, constraints,
operating policy). operating policy).
- **Starting, cancelling, or overriding** any task's status. - **Starting, cancelling, or overriding** any task's status.
- **Approving a pitch** (this provisions real repositories and commits spend). - **Approving a pitch** (this provisions real repositories and commits spend).
- Posting **announcements** or notifying the whole company. - Posting **announcements** or notifying the whole company.
For everything in that list: summarize the action and its blast radius in one For everything in that list: summarize the action and its blast radius in one or two lines, then ask the CEO to confirm. Do not execute until they confirm.
or two lines, then ask the CEO to confirm. Do not execute until they confirm.
## Your authority is the CEO's, exercised on command ## Your authority is the CEO's, exercised on command
When you carry out a directive, you act with the CEO's authority — but that When you carry out a directive, you act with the CEO's authority — but that authority is scoped and routed through the same enforcement every other action goes through. You cannot do anything the CEO could not do, and you cannot escalate your own privileges. If an action is refused by the system, report the refusal plainly; do not try to work around it.
authority is scoped and routed through the same enforcement every other action
goes through. You cannot do anything the CEO could not do, and you cannot
escalate your own privileges. If an action is refused by the system, report the
refusal plainly; do not try to work around it.
## How you work ## How you work
- Keep replies tight and decision-oriented. The CEO is busy; lead with the - Keep replies tight and decision-oriented. The CEO is busy; lead with the answer, then the supporting detail.
answer, then the supporting detail. - When you need information, read it — don't guess. Ground every claim about company state in what you actually read.
- When you need information, read it — don't guess. Ground every claim about
company state in what you actually read.
- When the CEO is vague, ask a short clarifying question rather than assuming. - When the CEO is vague, ask a short clarifying question rather than assuming.
- Never invent agents, channels, tasks, or numbers. If you don't know, say so - Never invent agents, channels, tasks, or numbers. If you don't know, say so and offer to look it up.
and offer to look it up. - You do not write code, open PRs, or merge. You coordinate and inform; the cells and PMs execute, and the CEO decides.
- You do not write code, open PRs, or merge. You coordinate and inform; the
cells and PMs execute, and the CEO decides.
## Anti-patterns ## Anti-patterns
- ❌ Doing anything the CEO did not ask for. - ❌ Doing anything the CEO did not ask for.
- ❌ Executing a gated action without an explicit confirmation. - ❌ Executing a gated action without an explicit confirmation.
- ❌ Talking to other agents on your own initiative, or trying to run the - ❌ Talking to other agents on your own initiative, or trying to run the delivery lifecycle yourself.
delivery lifecycle yourself.
- ❌ Presenting guesses as facts about company state. - ❌ Presenting guesses as facts about company state.
- ❌ Attempting to widen your own authority or bypass a refusal. - ❌ Attempting to widen your own authority or bypass a refusal.
+2 -8
View File
@@ -17,10 +17,7 @@ claude # Login via browser
## Quick Start (NAS/Server) ## Quick Start (NAS/Server)
Everything runs in Docker - no need to install Python/uv on the host. There Everything runs in Docker - no need to install Python/uv on the host. There are two ways to get the stack: **pull the pre-built images** (every release publishes them) or **build from source**. Both start from a clone, which gives you the compose files, the nginx config, and `.env.example`.
are two ways to get the stack: **pull the pre-built images** (every release
publishes them) or **build from source**. Both start from a clone, which gives
you the compose files, the nginx config, and `.env.example`.
```bash ```bash
# 1. Clone the project # 1. Clone the project
@@ -44,10 +41,7 @@ docker compose -f docker-compose.registry.yml up -d
docker compose -f docker-compose.registry.yml logs -f orchestrator docker compose -f docker-compose.registry.yml logs -f orchestrator
``` ```
Choose the registry and version with `ROBOCO_REGISTRY` (`ghcr.io/rennf93` or Choose the registry and version with `ROBOCO_REGISTRY` (`ghcr.io/rennf93` or `docker.io/renzof93`) and `ROBOCO_VERSION` (`latest` or a pinned release such as `0.5.0`). The orchestrator pulls and spawns the matching pre-built agent images on demand.
`docker.io/renzof93`) and `ROBOCO_VERSION` (`latest` or a pinned release such
as `0.5.0`). The orchestrator pulls and spawns the matching pre-built agent
images on demand.
### Option B — Build from source ### Option B — Build from source
+1 -2
View File
@@ -14,5 +14,4 @@ Documentation for the Backend Cell team.
## Contributing ## Contributing
Backend team members should request documentation updates through the Cell PM. Backend team members should request documentation updates through the Cell PM. Only the Backend Documenter (be-doc) can write to this directory.
Only the Backend Documenter (be-doc) can write to this directory.
+1 -2
View File
@@ -11,5 +11,4 @@ Documentation for features organized by team.
## Access ## Access
Each team subdirectory follows the same access pattern as the main team docs. Each team subdirectory follows the same access pattern as the main team docs. The `/shared/` directory is readable by all and writable by any documenter.
The `/shared/` directory is readable by all and writable by any documenter.
+1 -2
View File
@@ -14,5 +14,4 @@ Documentation for the Frontend Cell team.
## Contributing ## Contributing
Frontend team members should request documentation updates through the Cell PM. Frontend team members should request documentation updates through the Cell PM. Only the Frontend Documenter (fe-doc) can write to this directory.
Only the Frontend Documenter (fe-doc) can write to this directory.
+39 -139
View File
@@ -2,46 +2,25 @@
![Twelve-second looping preview of the RoboCo control panel — the org tree, a task in progress, and an approval queue.](videos/panel-teaser.gif) ![Twelve-second looping preview of the RoboCo control panel — the org tree, a task in progress, and an approval queue.](videos/panel-teaser.gif)
RoboCo is a virtual software company — 22 AI agents and one human: you. Not a RoboCo is a virtual software company — 22 AI agents and one human: you. Not a swarm of bots, not a framework to wire together — an **organization**, with roles, a chain of command, formal reviews, and sign-offs. You don't micromanage it; you run it like a CEO. Drop work in at the top and the company carries it all the way through planning, building, review, and documentation, then brings it back to your desk for the final word. You act at the two ends; the organization fills in everything between.
swarm of bots, not a framework to wire together — an **organization**, with
roles, a chain of command, formal reviews, and sign-offs. You don't micromanage
it; you run it like a CEO. Drop work in at the top and the company carries it all
the way through planning, building, review, and documentation, then brings it
back to your desk for the final word. You act at the two ends; the organization
fills in everything between.
What keeps twenty-two agents from dissolving into noise is that RoboCo is What keeps twenty-two agents from dissolving into noise is that RoboCo is relentlessly opinionated about *how* work happens: everything is a task, no task moves without acceptance criteria, and every task walks the same strict lifecycle — built, QA'd, documented, PM-reviewed, approved — each step gated by role. The structure is the point. It is what turns a roster of models into a company that actually ships.
relentlessly opinionated about *how* work happens: everything is a task, no task
moves without acceptance criteria, and every task walks the same strict lifecycle
— built, QA'd, documented, PM-reviewed, approved — each step gated by role. The
structure is the point. It is what turns a roster of models into a company that
actually ships.
And the proof is this page. The screenshots below aren't a mock-up: they follow And the proof is this page. The screenshots below aren't a mock-up: they follow RoboCo building one of its *own* features — the **Prompter**, the task-authoring page now living in this very control panel. RoboCo's agents scoped it, built it across three cells, failed and re-ran its QA, documented it, and opened the real pull request you'll see at the end. RoboCo builds RoboCo — that is the whole proof of concept.
RoboCo building one of its *own* features — the **Prompter**, the task-authoring
page now living in this very control panel. RoboCo's agents scoped it, built it
across three cells, failed and re-ran its QA, documented it, and opened the real
pull request you'll see at the end. RoboCo builds RoboCo — that is the whole
proof of concept.
> The panel is your one window into the company. Every task, agent, message, > The panel is your one window into the company. Every task, agent, message, journal, and pull request is live in front of you.
> journal, and pull request is live in front of you.
**Prefer video?** A [full screen-recording of the panel](videos/panel-full-walkthrough.mp4) **Prefer video?** A [full screen-recording of the panel](videos/panel-full-walkthrough.mp4) walks through every page and detail end-to-end — useful as a first tour before diving into the screenshots below.
walks through every page and detail end-to-end — useful as a first tour before
diving into the screenshots below.
![The RoboCo Command Center: per-cell health, the CEO approval queue, live metrics, auditor alerts, and recent activity.](images/overview_dashboard.png) ![The RoboCo Command Center: per-cell health, the CEO approval queue, live metrics, auditor alerts, and recent activity.](images/overview_dashboard.png)
*The **Command Center** — a glance tells you how each cell is doing, what's *The **Command Center** — a glance tells you how each cell is doing, what's waiting on your approval, how fast work is moving, and what just happened.*
waiting on your approval, how fast work is moving, and what just happened.*
--- ---
## The shape of the company ## The shape of the company
Work in RoboCo is always a **task**, and tasks nest into a tree that mirrors the Work in RoboCo is always a **task**, and tasks nest into a tree that mirrors the org itself:
org itself:
``` ```
CEO (you, the human) CEO (you, the human)
@@ -53,15 +32,11 @@ CEO (you, the human)
└── Backend cell ── PM · 2 Devs · QA · Documenter └── Backend cell ── PM · 2 Devs · QA · Documenter
``` ```
In practice, one feature becomes a small tree of work — a parent task at the top, In practice, one feature becomes a small tree of work — a parent task at the top, a branch for each cell underneath, every node carrying its own status, git branch, and pull request:
a branch for each cell underneath, every node carrying its own status, git
branch, and pull request:
![The task tree for a feature: a Main PM parent task fanned out to UX/UI, Frontend, and Backend cell tasks, each with a live status and a GitHub branch.](images/run.png) ![The task tree for a feature: a Main PM parent task fanned out to UX/UI, Frontend, and Backend cell tasks, each with a live status and a GitHub branch.](images/run.png)
*A feature in motion. The parent task fans out to the UX/UI, Frontend, and *A feature in motion. The parent task fans out to the UX/UI, Frontend, and Backend cells, and each child moves through its own lifecycle — in progress, awaiting review, completed — on its own branch.*
Backend cells, and each child moves through its own lifecycle — in progress,
awaiting review, completed — on its own branch.*
--- ---
@@ -69,85 +44,53 @@ awaiting review, completed — on its own branch.*
### 1 · It starts with you ### 1 · It starts with you
You describe what you want — a feature, a fix, an entire product. The way in is You describe what you want — a feature, a fix, an entire product. The way in is the **Task Assistant** — which is the **Prompter** itself, the very feature whose build the rest of this page follows. (You're about to use the tool RoboCo built for itself; further down, you'll watch the company build it.) Instead of filling a form from memory, you give it a rough idea and it reads your *actual* codebase, asks a few sharp questions, and hands back a properly-formed task — an objective, a per-cell breakdown, and the acceptance criteria that define what "finished" really means.
the **Task Assistant** — which is the **Prompter** itself, the very feature whose
build the rest of this page follows. (You're about to use the tool RoboCo built
for itself; further down, you'll watch the company build it.) Instead of filling
a form from memory, you give it a rough idea and it reads your *actual* codebase,
asks a few sharp questions, and hands back a properly-formed task — an objective,
a per-cell breakdown, and the acceptance criteria that define what "finished"
really means.
![The Task Assistant's scope form: pick the project or product to work in, then describe what you want to build.](images/start_prompter.png) ![The Task Assistant's scope form: pick the project or product to work in, then describe what you want to build.](images/start_prompter.png)
*Where it starts — point the assistant at a project (one repo) or a product *Where it starts — point the assistant at a project (one repo) or a product (several), drop in a rough idea, and it spins up an agent that reads that code before it says a word.*
(several), drop in a rough idea, and it spins up an agent that reads that code
before it says a word.*
![The Task Assistant chat opening: the idea is in, and the agent is cloning the repo and reading the code before it answers.](images/prompter_run_1.png) ![The Task Assistant chat opening: the idea is in, and the agent is cloning the repo and reading the code before it answers.](images/prompter_run_1.png)
*No canned questions. The agent clones the scope and reads the real surface *No canned questions. The agent clones the scope and reads the real surface first, so everything it asks and proposes is grounded in what your code actually does.*
first, so everything it asks and proposes is grounded in what your code actually
does.*
<!-- Optional: re-capture prompter_run_2 after the markdown-rendering fix ships (its headers will render cleanly instead of as raw ###). --> <!-- Optional: re-capture prompter_run_2 after the markdown-rendering fix ships (its headers will render cleanly instead of as raw ###). -->
![The agent's grounded analysis: a read of the existing surface, what's missing, where the feature should live, and a proposed shape — citing real files and pages.](images/prompter_run_2.png) ![The agent's grounded analysis: a read of the existing surface, what's missing, where the feature should live, and a proposed shape — citing real files and pages.](images/prompter_run_2.png)
*It comes back having done the homework — naming the real pages, services, and *It comes back having done the homework — naming the real pages, services, and files, laying out what to build and where, and refining with you over a couple of turns until the spec is right.*
files, laying out what to build and where, and refining with you over a couple of
turns until the spec is right.*
<!-- prompter_draft_card.png is the captured smoke shot; optionally re-capture after the draft-card cell-badge dedupe ships, for cleaner "Board-led across Backend Frontend" badges. --> <!-- prompter_draft_card.png is the captured smoke shot; optionally re-capture after the draft-card cell-badge dedupe ships, for cleaner "Board-led across Backend Frontend" badges. -->
![The draft proposal card: the finished task — objective, per-cell work, and acceptance criteria — with three choices: Keep chatting, Board review & Start, or Approve & Start.](images/prompter_draft_card.png) ![The draft proposal card: the finished task — objective, per-cell work, and acceptance criteria — with three choices: Keep chatting, Board review & Start, or Approve & Start.](images/prompter_draft_card.png)
*The proposal, ready to launch. Keep chatting to refine it, send it to the *The proposal, ready to launch. Keep chatting to refine it, send it to the **Board** for review, or approve it straight to the Main PM — your call, on one card.*
**Board** for review, or approve it straight to the Main PM — your call, on one
card.*
![The Task Assistant's confirmation: the task has been created and handed to the company.](images/prompter_task_accepted.png) ![The Task Assistant's confirmation: the task has been created and handed to the company.](images/prompter_task_accepted.png)
![The created task, live: its objective, the per-cell breakdown, status, and assignment — exactly as the company will work it.](images/prompter_task_created.png) ![The created task, live: its objective, the per-cell breakdown, status, and assignment — exactly as the company will work it.](images/prompter_task_created.png)
*From a rough sentence to a real, scoped task in a single chat — acceptance *From a rough sentence to a real, scoped task in a single chat — acceptance criteria and all, already moving through the company.*
criteria and all, already moving through the company.*
From here, every task follows the path you chose for it. To show that journey end From here, every task follows the path you chose for it. To show that journey end to end, the rest of this page follows the **Prompter's own** trip through the company — from this same starting point to a merged pull request. Send a task to the **Board** and their job is to pin it down: the Product Owner and Head of Marketing turn the draft into a settled spec, sharpening the requirements and the acceptance criteria before anyone writes a line of code. The Auditor watches the whole time but never interferes.
to end, the rest of this page follows the **Prompter's own** trip through the
company — from this same starting point to a merged pull request. Send a task to
the **Board** and their job is to pin it down: the Product Owner and Head of
Marketing turn the draft into a settled spec, sharpening the requirements and the
acceptance criteria before anyone writes a line of code. The Auditor watches the
whole time but never interferes.
![A Board review session: the Product Owner writing out requirements and acceptance criteria for a task.](images/chat_session.png) ![A Board review session: the Product Owner writing out requirements and acceptance criteria for a task.](images/chat_session.png)
*The Product Owner working a task over — pinning down the requirements and the *The Product Owner working a task over — pinning down the requirements and the must-haves before anyone writes a line of code.*
must-haves before anyone writes a line of code.*
![A Board review session for the Prompter feature, with the Product Owner and Head of Marketing each recording their take — positioning, naming, the model-selector UX — against the task.](images/po_hom_review.png) ![A Board review session for the Prompter feature, with the Product Owner and Head of Marketing each recording their take — positioning, naming, the model-selector UX — against the task.](images/po_hom_review.png)
*Two seats at the table. The Product Owner and the Head of Marketing review the *Two seats at the table. The Product Owner and the Head of Marketing review the same task from their own angles and put their reasoning on the record — this is the Board building the actual spec for the Prompter, the feature this whole walkthrough follows.*
same task from their own angles and put their reasoning on the record — this is
the Board building the actual spec for the Prompter, the feature this whole
walkthrough follows.*
### 2 · Nothing moves without your green light ### 2 · Nothing moves without your green light
The Board hands the reviewed task back to you as a **notification** and waits. The Board hands the reviewed task back to you as a **notification** and waits. You make one call: send it forward, or send it back. Approve it, and the **Main PM** picks it up, splits it across the cells, and sets them running.
You make one call: send it forward, or send it back. Approve it, and the **Main
PM** picks it up, splits it across the cells, and sets them running.
![The board-review notification waiting on the CEO's decision to start the work or send it back.](images/notifications.png) ![The board-review notification waiting on the CEO's decision to start the work or send it back.](images/notifications.png)
*The Board's verdict lands in your notifications and pauses there. A single *The Board's verdict lands in your notifications and pauses there. A single approval is what turns the whole company on.*
approval is what turns the whole company on.*
![The board-review-complete notification for the Prompter task: the Product Owner and Head of Marketing have both reviewed it, and it is now ready for the CEO's Approve & Start decision or rejection.](images/ceo_review_notif.png) ![The board-review-complete notification for the Prompter task: the Product Owner and Head of Marketing have both reviewed it, and it is now ready for the CEO's Approve & Start decision or rejection.](images/ceo_review_notif.png)
*The notification itself, spelled out: the Board has finished, the task is *The notification itself, spelled out: the Board has finished, the task is recorded, and nothing happens until you say so — Approve & Start hands it to the Main PM; reject it and it goes back. This is the first of the only two moments the company needs you.*
recorded, and nothing happens until you say so — Approve & Start hands it to the
Main PM; reject it and it goes back. This is the first of the only two moments
the company needs you.*
![The CEO's pending-approval queue with a task card showing the green "Approve & Start" button.](images/approve_task.png) ![The CEO's pending-approval queue with a task card showing the green "Approve & Start" button.](images/approve_task.png)
@@ -155,115 +98,72 @@ the company needs you.*
### 3 · The cells take over ### 3 · The cells take over
Underneath the Main PM are three cells — **UX/UI, Frontend, Backend** — each a Underneath the Main PM are three cells — **UX/UI, Frontend, Backend** — each a small team with its own PM. Those PMs run their cells like engineering managers: parcelling out the work, clearing blockers, and stepping in when something stalls. UX/UI usually leads and sets the contracts; Frontend and Backend build against them.
small team with its own PM. Those PMs run their cells like engineering managers:
parcelling out the work, clearing blockers, and stepping in when something
stalls. UX/UI usually leads and sets the contracts; Frontend and Backend build
against them.
![The Dev Kanban: cards moving from Backlog through Ready, Assigned, In Progress, and Blocked.](images/kanban.png) ![The Dev Kanban: cards moving from Backlog through Ready, Assigned, In Progress, and Blocked.](images/kanban.png)
*A cell at work, seen as a board — tasks flow from backlog to done, and the *A cell at work, seen as a board — tasks flow from backlog to done, and the role tabs let you watch it from the developer's, QA's, or PM's seat.*
role tabs let you watch it from the developer's, QA's, or PM's seat.*
### 4 · The work gets done — and checked ### 4 · The work gets done — and checked
This is where it's actually built. Developers write the code and open pull This is where it's actually built. Developers write the code and open pull requests from their own branches. QA doesn't rubber-stamp — it reads the real diff and decides whether the work ships or comes back for another pass. Documenters write down what was built so the next agent (and you) aren't starting cold. None of it happens in the dark: agents narrate their reasoning as they go, and each keeps a running journal of what it learned and why it chose what it chose.
requests from their own branches. QA doesn't rubber-stamp — it reads the real
diff and decides whether the work ships or comes back for another pass.
Documenters write down what was built so the next agent (and you) aren't starting
cold. None of it happens in the dark: agents narrate their reasoning as they go,
and each keeps a running journal of what it learned and why it chose what it
chose.
![A task's notes after a QA review: the developer's notes, a QA section marked Failed, and a silent Auditor column — all on the same task.](images/qa_fail.png) ![A task's notes after a QA review: the developer's notes, a QA section marked Failed, and a silent Auditor column — all on the same task.](images/qa_fail.png)
*QA earning its seat. On this Prompter task it read the work, marked it *QA earning its seat. On this Prompter task it read the work, marked it **failed**, and sent it back — the developer's notes and the QA verdict sit side by side on the record, with the Auditor watching the whole exchange. Real review, not a rubber stamp; the gate only opens when the work is right.*
**failed**, and sent it back — the developer's notes and the QA verdict sit side
by side on the record, with the Auditor watching the whole exchange. Real review,
not a rubber stamp; the gate only opens when the work is right.*
![Agent Journals: per-agent reflections, decision logs, and learnings.](images/journaling.png) ![Agent Journals: per-agent reflections, decision logs, and learnings.](images/journaling.png)
*Every agent keeps a journal — reflections, decisions, and lessons. Between that *Every agent keeps a journal — reflections, decisions, and lessons. Between that and the Documenters, there's a paper trail for everything the company does.*
and the Documenters, there's a paper trail for everything the company does.*
### 5 · The work converges ### 5 · The work converges
Once a cell's piece is green and documented, its PM folds those branches up into Once a cell's piece is green and documented, its PM folds those branches up into the Main PM's integration branch. Three independent streams of work come back together into one. Each task brings its branch, pull request, commits, and docs along with it:
the Main PM's integration branch. Three independent streams of work come back
together into one. Each task brings its branch, pull request, commits, and docs
along with it:
![A completed task showing its branch, pull request, commits, and documentation.](images/task_details.png) ![A completed task showing its branch, pull request, commits, and documentation.](images/task_details.png)
*One finished unit — branch, pull request, commits, and docs all attached. This *One finished unit — branch, pull request, commits, and docs all attached. This is the thing that travels up the merge chain.*
is the thing that travels up the merge chain.*
![The integrated pull request's commit list: one verified commit per cell — the UX/UI design specs and the backend chat endpoint — each co-authored by the agent that wrote it.](images/opened_final_pr_commits.png) ![The integrated pull request's commit list: one verified commit per cell — the UX/UI design specs and the backend chat endpoint — each co-authored by the agent that wrote it.](images/opened_final_pr_commits.png)
*Three streams becoming one history. Each cell's work lands as its own *Three streams becoming one history. Each cell's work lands as its own **verified** commit, co-authored by the agent that wrote it — the UX/UI design, the backend endpoint, the frontend page — folded together into the single pull equest that comes back to you.*
**verified** commit, co-authored by the agent that wrote it — the UX/UI design,
the backend endpoint, the frontend page — folded together into the single pull
request that comes back to you.*
### 6 · The last call is yours ### 6 · The last call is yours
The cells' work is folded up, the Main PM opens the **final pull request** into The cells' work is folded up, the Main PM opens the **final pull request** into `master`, and the company goes quiet. The decision comes back to exactly where it started — with you. You're the only one who ever touches `master`, and anything waiting on you sits in the **CEO Approval Queue** until you act.
`master`, and the company goes quiet. The decision comes back to exactly where it
started — with you. You're the only one who ever touches `master`, and anything
waiting on you sits in the **CEO Approval Queue** until you act.
![The final CEO approval notification: the integrated Prompter PR is ready, all three cells delivered and QA-passed, awaiting the CEO's review and merge.](images/ceo_approval_notif.png) ![The final CEO approval notification: the integrated Prompter PR is ready, all three cells delivered and QA-passed, awaiting the CEO's review and merge.](images/ceo_approval_notif.png)
*The hand-off back to you. The integrated PR is open, every cell has delivered, *The hand-off back to you. The integrated PR is open, every cell has delivered, QA is green — and it waits. Nothing reaches `master` without your word.*
QA is green — and it waits. Nothing reaches `master` without your word.*
![The integrated pull request open on GitHub, in the repository's Pull Requests list.](images/opened_final_pr.png) ![The integrated pull request open on GitHub, in the repository's Pull Requests list.](images/opened_final_pr.png)
*And it is a real pull request, on the real repository — not a simulation. The *And it is a real pull request, on the real repository — not a simulation. The company's work shows up exactly where any engineer would look for it.*
company's work shows up exactly where any engineer would look for it.*
![The pull request's description: the objective, what the task builds, the per-cell breakdown, and the notes the company wrote for it.](images/opened_final_pr_body.png) ![The pull request's description: the objective, what the task builds, the per-cell breakdown, and the notes the company wrote for it.](images/opened_final_pr_body.png)
*Open it and the whole brief is there — the objective, what was built, the *Open it and the whole brief is there — the objective, what was built, the board-led split across the three cells, and the company's own notes — written by RoboCo, for you to read before you decide.*
board-led split across the three cells, and the company's own notes — written by
RoboCo, for you to read before you decide.*
![The pull request's Files changed tab: the actual diff — migrations, API, and panel components — the company is asking to merge.](images/opened_final_pr_changes.png) ![The pull request's Files changed tab: the actual diff — migrations, API, and panel components — the company is asking to merge.](images/opened_final_pr_changes.png)
*The real diff, laid out for you to inspect — the migrations, the endpoints, the *The real diff, laid out for you to inspect — the migrations, the endpoints, the panel components. This is the substance you are signing off on.*
panel components. This is the substance you are signing off on.*
![The CEO's actions on the awaiting-approval task: Approve & Merge, Request Changes, or Cancel.](images/approve_button_merge_rework.png) ![The CEO's actions on the awaiting-approval task: Approve & Merge, Request Changes, or Cancel.](images/approve_button_merge_rework.png)
*Your two words. **Approve & Merge** and it ships to `master`; **Request Changes** *Your two words. **Approve & Merge** and it ships to `master`; **Request Changes** and it goes around for another lap. The last call has the same shape as the first — one decision, yours alone.*
and it goes around for another lap. The last call has the same shape as the first
— one decision, yours alone.*
--- ---
## And round it goes ## And round it goes
You handed the company a task; it scoped it, built it, failed and re-ran its own You handed the company a task; it scoped it, built it, failed and re-ran its own QA, documented it, and brought it back as a single pull request for your sign-off. That's one complete pass.
QA, documented it, and brought it back as a single pull request for your
sign-off. That's one complete pass.
![The full task table for the Prompter feature: a parent task awaiting CEO approval over its completed UX/UI, Frontend, and Backend child tasks.](images/all_tasks_final_state.png) ![The full task table for the Prompter feature: a parent task awaiting CEO approval over its completed UX/UI, Frontend, and Backend child tasks.](images/all_tasks_final_state.png)
*The whole tree in its final state — the parent waiting on your approval, every *The whole tree in its final state — the parent waiting on your approval, every cell's task done beneath it. One feature, start to finish, with you at only the two ends.*
cell's task done beneath it. One feature, start to finish, with you at only the
two ends.*
And the feature in these screenshots is the proof. The **Prompter** wasn't built And the feature in these screenshots is the proof. The **Prompter** wasn't built for a demo — it's a real page RoboCo's agents shipped to RoboCo's own control panel. A company building its own product, in front of you, is the whole point of RoboCo. What makes that hold together isn't a clever model or a lucky run; it's the **organization** — the roles, the gated lifecycle, the reviews and the sign-offs that keep twenty-two agents moving as a company instead of a crowd. Run as many of these passes as you like, across as many projects as you like.
for a demo — it's a real page RoboCo's agents shipped to RoboCo's own control
panel. A company building its own product, in front of you, is the whole point of
RoboCo. What makes that hold together isn't a clever model or a lucky run; it's
the **organization** — the roles, the gated lifecycle, the reviews and the
sign-offs that keep twenty-two agents moving as a company instead of a crowd. Run
as many of these passes as you like, across as many projects as you like.
--- ---
*RoboCo is early-stage, work-in-progress software (v0) — expect rough edges. The *RoboCo is early-stage, work-in-progress software (v0) — expect rough edges. The [README](../README.md) covers setup, architecture, and the security model.*
[README](../README.md) covers setup, architecture, and the security model.*
+1 -2
View File
@@ -73,8 +73,7 @@ delegate(assigned_to="00000000-0000-0000-0001-000000000001", ...)
## Usage ## Usage
Verbs take the `task_id` UUID directly (returned by `give_me_work()` / Verbs take the `task_id` UUID directly (returned by `give_me_work()` / `triage()`); recipient/assignee arguments accept either a slug or a UUID:
`triage()`); recipient/assignee arguments accept either a slug or a UUID:
```python ```python
i_will_work_on(task_id) # task_id is a UUID i_will_work_on(task_id) # task_id is a UUID
dm(recipient="be-qa", text="...", task_id="...") # slug recipient dm(recipient="be-qa", text="...", task_id="...") # slug recipient
+2 -7
View File
@@ -44,18 +44,13 @@ Auditor has silent read access (in these channels' `silent_roles`) to:
- `pm-all` - `pm-all`
- `doc-all` - `doc-all`
Auditor does NOT appear in member lists but CAN read. On the two management 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.)
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 ## Privileged Access
These roles bypass normal membership checks: These roles bypass normal membership checks:
- **CEO**: Full access everywhere - **CEO**: Full access everywhere
- **Auditor**: Silent read on cell + cross-cell channels; read/write on the - **Auditor**: Silent read on cell + cross-cell channels; read/write on the management channels
management channels
- **Main PM**: Read access to all cell channels - **Main PM**: Read access to all cell channels
## Using Channels ## Using Channels
+4 -15
View File
@@ -33,9 +33,7 @@
| #main-pm-board | Main PM, Product Owner, Head Marketing, Auditor | | #main-pm-board | Main PM, Product Owner, Head Marketing, Auditor |
| #board-private | Product Owner, Head Marketing, Auditor, CEO, Main PM | | #board-private | Product Owner, Head Marketing, Auditor, CEO, Main PM |
In both management channels the Auditor has read **and** write (it is NOT 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.
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 ## Special Channels
@@ -51,12 +49,7 @@ Auditor has **silent read access** to the cell and cross-cell channels:
- Cannot send messages there - Cannot send messages there
- Observes all activity - Observes all activity
The Auditor is silent only on cell + cross-cell channels (it is in those 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.
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 ## Channel Access Rules
@@ -72,8 +65,7 @@ practice it observes rather than posts.
## Messaging ## Messaging
Agents post to channels with the `say` content tool (there is no Agents post to channels with the `say` content tool (there is no `roboco_message_send` tool):
`roboco_message_send` tool):
```python ```python
say( say(
@@ -83,7 +75,4 @@ say(
) )
``` ```
For direct agent-to-agent messages, use `dm(recipient, text)` (same-cell 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)`.
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)`.
+8 -27
View File
@@ -1,9 +1,6 @@
# Company Layer (Goals, Pitches, Strategy) # Company Layer (Goals, Pitches, Strategy)
The **company layer** sits above day-to-day delivery: the CEO's charter, the The **company layer** sits above day-to-day delivery: the CEO's charter, the pitch pipeline, and a background strategy watcher. The charter is always available (empty until set); the research, provisioning, and strategy-engine pieces are **opt-in and default-off** — the org runs fine without any of them.
pitch pipeline, and a background strategy watcher. The charter is always
available (empty until set); the research, provisioning, and strategy-engine
pieces are **opt-in and default-off** — the org runs fine without any of them.
## The Charter (Company Goals) ## The Charter (Company Goals)
@@ -16,14 +13,12 @@ A single, CEO-owned charter is the company's north star. It has four parts:
| `constraints` | Hard limits the company must respect | | `constraints` | Hard limits the company must respect |
| `operating_policy` | Operating rules (e.g. a monthly budget cap) | | `operating_policy` | Operating rules (e.g. a monthly budget cap) |
The charter is a **singleton**, and it is injected — compactly — into **every The charter is a **singleton**, and it is injected — compactly — into **every agent's briefing**, so all work is goal-aware without anyone fetching it.
agent's briefing**, so all work is goal-aware without anyone fetching it.
- `GET /api/company-goals` — read (any agent) - `GET /api/company-goals` — read (any agent)
- `PUT /api/company-goals` — write (CEO only) - `PUT /api/company-goals` — write (CEO only)
It is empty until the CEO sets it; an empty charter simply contributes nothing It is empty until the CEO sets it; an empty charter simply contributes nothing to briefings.
to briefings.
## Pitches ## Pitches
@@ -35,30 +30,17 @@ A **pitch** is a proposal for new product work. Its lifecycle is small:
| `provisioned` | Approved — turned into a product / project(s) | | `provisioned` | Approved — turned into a product / project(s) |
| `rejected` | Declined | | `rejected` | Declined |
When a pitch is approved and **provisioning is enabled** When a pitch is approved and **provisioning is enabled** (`ROBOCO_PROVISIONING_ENABLED` plus a GitHub token and org), it can auto-create the product and its repositories (recorded in `provisioned_product_id` / `provisioned_project_ids`). With provisioning off, approval just records the decision.
(`ROBOCO_PROVISIONING_ENABLED` plus a GitHub token and org), it can auto-create
the product and its repositories (recorded in `provisioned_product_id` /
`provisioned_project_ids`). With provisioning off, approval just records the
decision.
## Strategy Engine ## Strategy Engine
The Strategy Engine is a **notify-only** background watcher The Strategy Engine is a **notify-only** background watcher (`ROBOCO_STRATEGY_ENGINE_ENABLED`, default off). Each cycle it `assess()`es the company against its standing goals and emits `StrategyObservation`s — each a `kind`, a `summary`, and a `detail` — for example `idle` (capacity sitting unused) or `stranded_blocked` (work stuck in `blocked`). It only **observes and surfaces**; it never acts on its own.
(`ROBOCO_STRATEGY_ENGINE_ENABLED`, default off). Each cycle it `assess()`es the
company against its standing goals and emits `StrategyObservation`s — each a
`kind`, a `summary`, and a `detail` — for example `idle` (capacity sitting
unused) or `stranded_blocked` (work stuck in `blocked`). It only **observes and
surfaces**; it never acts on its own.
Those observations are the "needs your attention" signals shown on the Those observations are the "needs your attention" signals shown on the Dashboard, served by `GET /api/cockpit/signals`.
Dashboard, served by `GET /api/cockpit/signals`.
## The Secretary ## The Secretary
The CEO's chief-of-staff reads this layer (`read_company_state` returns the The CEO's chief-of-staff reads this layer (`read_company_state` returns the charter, task counts, pending pitches, and any directives awaiting confirmation) and acts on it via gated directives. See `docs/rag/roles/secretary.md`.
charter, task counts, pending pitches, and any directives awaiting
confirmation) and acts on it via gated directives. See
`docs/rag/roles/secretary.md`.
## Feature Toggles ## Feature Toggles
@@ -68,5 +50,4 @@ confirmation) and acts on it via gated directives. See
| `ROBOCO_STRATEGY_ENGINE_ENABLED` | off | The strategy watcher loop | | `ROBOCO_STRATEGY_ENGINE_ENABLED` | off | The strategy watcher loop |
| `ROBOCO_PROVISIONING_ENABLED` | off | Pitch → auto-provisioned repos | | `ROBOCO_PROVISIONING_ENABLED` | off | Pitch → auto-provisioned repos |
All are additive: with every toggle off, the company layer is just the charter All are additive: with every toggle off, the company layer is just the charter plus the pitch record.
plus the pitch record.
+2 -6
View File
@@ -49,10 +49,7 @@ escalate_up(
) )
``` ```
Auto-routes to your escalation target. You CANNOT choose a different 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.
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 (Main PM / Board Only) ## CEO Escalation (Main PM / Board Only)
@@ -66,8 +63,7 @@ escalate_to_ceo(
Requirements: Requirements:
- Task in `awaiting_pm_review` - Task in `awaiting_pm_review`
- PR exists - PR exists
- Only Main PM, Product Owner, or Head of Marketing 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)
(Cell PMs cannot — they `escalate_up` to Main PM first)
## Cannot Skip Levels ## Cannot Skip Levels
+2 -6
View File
@@ -38,18 +38,14 @@ CEO (Renzo - Human)
## On-Demand Roles (Human-Facing) ## On-Demand Roles (Human-Facing)
Two of the 22 — the Prompter (Intake) and the Secretary — sit outside the Two of the 22 — the Prompter (Intake) and the Secretary — sit outside the standing delivery org above. They are **human-only** and **spawned on demand** as live chat sessions; they are counted among the 22, but unlike the standing org they have no lifecycle verbs and no outward agent comms:
standing delivery org above. They are **human-only** and **spawned on demand**
as live chat sessions; they are counted among the 22, but unlike the standing
org they have no lifecycle verbs and no outward agent comms:
| Role | Purpose | | Role | Purpose |
|------|---------| |------|---------|
| Prompter (Intake) | Interviews the CEO and drafts a board-ready task | | Prompter (Intake) | Interviews the CEO and drafts a board-ready task |
| Secretary | The CEO's chief-of-staff; reads company state and runs gated CEO directives | | Secretary | The CEO's chief-of-staff; reads company state and runs gated CEO directives |
Neither has lifecycle verbs or outward agent comms. See Neither has lifecycle verbs or outward agent comms. See [Prompter](../roles/prompter.md) and [Secretary](../roles/secretary.md).
`docs/rag/roles/prompter.md` and `docs/rag/roles/secretary.md`.
## Cells ## Cells
+9 -24
View File
@@ -29,16 +29,10 @@ What each role can do in the system.
| Docs Complete (`i_documented`) | - | - | - | - | - | - | - | Yes | | Docs Complete (`i_documented`) | - | - | - | - | - | - | - | Yes |
Notes (verified against `roboco/foundation/policy/lifecycle.py`): Notes (verified against `roboco/foundation/policy/lifecycle.py`):
- **Create / Assign** (`create_subtask`, `delegate`) are PM-only: `cell_pm` - **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.
and `main_pm`. The Board (Product Owner, Head Marketing), Auditor, and CEO - **Cancel** is allowed to PM roles + CEO (`cell_pm`, `main_pm`, `ceo`). The Board and Auditor CANNOT cancel.
do NOT create or assign tasks via the gateway. - **Complete** (final approve/merge) is PM-only (`cell_pm`, `main_pm`). The CEO acts only on tasks escalated to `awaiting_ceo_approval`.
- **Cancel** is allowed to PM roles + CEO (`cell_pm`, `main_pm`, `ceo`). The - **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.
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 ## Index Permissions
@@ -55,9 +49,7 @@ Note: Board (Product Owner, Head Marketing) can only index docs, not code.
## Notification Permissions ## Notification Permissions
Sending notifications means calling the `notify(target, text, priority)` Sending notifications means calling the `notify(target, text, priority)` content tool. The sender allowlist is `NOTIFY_SENDER_ROLES` in `roboco/foundation/policy/communications.py`.
content tool. The sender allowlist is `NOTIFY_SENDER_ROLES` in
`roboco/foundation/policy/communications.py`.
| Role | Can Send (`notify`) | Scope | | Role | Can Send (`notify`) | Scope |
|------|---------------------|-------| |------|---------------------|-------|
@@ -71,26 +63,19 @@ content tool. The sender allowlist is `NOTIFY_SENDER_ROLES` in
| qa | No | - | | qa | No | - |
| documenter | No | - | | documenter | No | - |
Non-senders (developer, qa, documenter, auditor) still communicate via 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`.
`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`.
## Task-Creator Roles ## Task-Creator Roles
These roles can create/assign tasks (`create_subtask`, `delegate` — PM-only These roles can create/assign tasks (`create_subtask`, `delegate` — PM-only per `lifecycle.py`):
per `lifecycle.py`):
- `main_pm` - `main_pm`
- `cell_pm` - `cell_pm`
The Board (`product_owner`, `head_marketing`), the Auditor, and the CEO do The Board (`product_owner`, `head_marketing`), the Auditor, and the CEO do NOT create or assign tasks through the gateway.
NOT create or assign tasks through the gateway.
## Cancellation Roles ## Cancellation Roles
These roles can cancel tasks (the `cancel` action's `allowed_roles` in These roles can cancel tasks (the `cancel` action's `allowed_roles` in `lifecycle.py` = PM roles + CEO):
`lifecycle.py` = PM roles + CEO):
- `cell_pm` - `cell_pm`
- `main_pm` - `main_pm`
- `ceo` - `ceo`
+2 -10
View File
@@ -16,17 +16,9 @@
## Acceptance-Criteria Tracking ## Acceptance-Criteria Tracking
Every task's `acceptance_criteria` get a parallel list of stable Every task's `acceptance_criteria` get a parallel list of stable `acceptance_criteria_ids` — one id per criterion, generated automatically when a task is created. The ids are stable across edits, so other tasks can reference a specific criterion.
`acceptance_criteria_ids` — one id per criterion, generated automatically when a
task is created. The ids are stable across edits, so other tasks can reference a
specific criterion.
When a parent task is decomposed, each subtask declares which parent criteria it When a parent task is decomposed, each subtask declares which parent criteria it covers in `parent_ac_refs` (set from the `covers_parent_criteria` argument to `delegate`). That child→parent link is what lets the org guarantee a decomposition actually covers the parent's full intent. See `docs/rag/workflows/task-planning.md` for the coverage gates and the PM's coverage briefing.
covers in `parent_ac_refs` (set from the `covers_parent_criteria` argument to
`delegate`). That child→parent link is what lets the org guarantee a
decomposition actually covers the parent's full intent. See
`docs/rag/workflows/task-planning.md` for the coverage gates and the PM's
coverage briefing.
## Task Types ## Task Types
+18 -45
View File
@@ -10,37 +10,25 @@ Agents call gateway verbs through three MCP servers, scoped per role:
| `roboco-do` | Content/write verbs (commit, note, say, dm, notify, evidence) | | `roboco-do` | Content/write verbs (commit, note, say, dm, notify, evidence) |
| `roboco-git-readonly` | Read-only git inspection (status, log, diff, branch_list) | | `roboco-git-readonly` | Read-only git inspection (status, log, diff, branch_list) |
Native shell git is blocked by the bash-guard hook for everyone. There is Native shell git is blocked by the bash-guard hook for everyone. There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr / _checkout` tool — write operations happen through the lifecycle verbs and the choreographer handles git as a side-effect.
**no** `roboco_git_commit / _push / _create_pr / _merge_pr / _checkout`
tool — write operations happen through the lifecycle verbs and the
choreographer handles git as a side-effect.
The canonical source of role → verb mapping is The canonical source of role → verb mapping is `roboco/services/gateway/role_config.py`. The tables below summarise it.
`roboco/services/gateway/role_config.py`. The tables below summarise it.
## Developer ## Developer
**Flow verbs (roboco-flow):** **Flow verbs (roboco-flow):** `give_me_work`, `i_will_work_on`, `open_pr`, `i_am_done`, `i_am_blocked`, `unclaim`, `resume`, `i_am_idle`
`give_me_work`, `i_will_work_on`, `open_pr`, `i_am_done`,
`i_am_blocked`, `unclaim`, `resume`, `i_am_idle`
**Content verbs (roboco-do):** **Content verbs (roboco-do):** `commit`, `note`, `say`, `dm`, `evidence`
`commit`, `note`, `say`, `dm`, `evidence`
**Read-only git (roboco-git-readonly):** all 4 (`status`, `log`, `diff`, **Read-only git (roboco-git-readonly):** all 4 (`status`, `log`, `diff`, `branch_list`)
`branch_list`)
**Workspace writes:** `Write` / `Edit` in **Workspace writes:** `Write` / `Edit` in `/data/workspaces/{project}/{team}/{agent-id}/` only.
`/data/workspaces/{project}/{team}/{agent-id}/` only.
## QA ## QA
**Flow verbs:** **Flow verbs:** `give_me_work`, `claim_review`, `pass`, `fail`, `unclaim`, `resume`, `i_am_idle`
`give_me_work`, `claim_review`, `pass`, `fail`, `unclaim`, `resume`,
`i_am_idle`
**Content verbs:** **Content verbs:** `note`, `say`, `dm`, `evidence` (no `commit` — QA does not write code)
`note`, `say`, `dm`, `evidence` (no `commit` — QA does not write code)
**Read-only git:** all 4 **Read-only git:** all 4
@@ -48,27 +36,19 @@ The canonical source of role → verb mapping is
## Documenter ## Documenter
**Flow verbs:** **Flow verbs:** `give_me_work`, `claim_doc_task`, `i_documented`, `unclaim`, `resume`, `i_am_idle`
`give_me_work`, `claim_doc_task`, `i_documented`, `unclaim`, `resume`,
`i_am_idle`
**Content verbs:** **Content verbs:** `commit`, `note`, `say`, `dm`, `evidence`
`commit`, `note`, `say`, `dm`, `evidence`
**Read-only git:** all 4 **Read-only git:** all 4
**Workspace writes:** docs files inside the agent's own workspace **Workspace writes:** docs files inside the agent's own workspace (`/data/workspaces/{project}/{team}/{agent-id}/`).
(`/data/workspaces/{project}/{team}/{agent-id}/`).
## Cell PM ## Cell PM
**Flow verbs:** **Flow verbs:** `give_me_work`, `i_will_plan`, `delegate`, `submit_up`, `triage`, `unblock`, `complete`, `escalate_up`, `unclaim`, `resume`, `i_am_idle`
`give_me_work`, `i_will_plan`, `delegate`, `submit_up`, `triage`,
`unblock`, `complete`, `escalate_up`, `unclaim`, `resume`, `i_am_idle`
**Content verbs:** **Content verbs:** `note`, `say`, `dm`, `notify`, `evidence` (no `commit` — PMs delegate code; merging the leaf PR happens automatically inside `complete`)
`note`, `say`, `dm`, `notify`, `evidence` (no `commit` — PMs delegate
code; merging the leaf PR happens automatically inside `complete`)
**Read-only git:** all 4 **Read-only git:** all 4
@@ -76,18 +56,13 @@ code; merging the leaf PR happens automatically inside `complete`)
## Main PM ## Main PM
**Flow verbs:** **Flow verbs:** `give_me_work`, `i_will_plan`, `delegate`, `triage_all`, `unblock`, `complete`, `escalate_up`, `escalate_to_ceo`, `unclaim`, `resume`, `i_am_idle`
`give_me_work`, `i_will_plan`, `delegate`, `triage_all`, `unblock`,
`complete`, `escalate_up`, `escalate_to_ceo`, `unclaim`, `resume`,
`i_am_idle`
**Content verbs:** **Content verbs:** `note`, `say`, `dm`, `notify`, `evidence`
`note`, `say`, `dm`, `notify`, `evidence`
**Read-only git:** all 4 **Read-only git:** all 4
**Workspace writes:** none. `complete` on a root parent task opens the **Workspace writes:** none. `complete` on a root parent task opens the master PR via the choreographer and escalates to CEO.
master PR via the choreographer and escalates to CEO.
## Board (Product Owner, Head of Marketing) ## Board (Product Owner, Head of Marketing)
@@ -101,8 +76,7 @@ master PR via the choreographer and escalates to CEO.
**Flow verbs:** `triage`, `i_am_idle` (read-only) **Flow verbs:** `triage`, `i_am_idle` (read-only)
**Content verbs:** `note` (scope=reflect), `evidence` (no `say` / `dm` **Content verbs:** `note` (scope=reflect), `evidence` (no `say` / `dm` — Auditor observes silently)
— Auditor observes silently)
**Read-only git:** none. **Read-only git:** none.
@@ -123,5 +97,4 @@ master PR via the choreographer and escalates to CEO.
| `roboco_git_*` (read-only) | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | | `roboco_git_*` (read-only) | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
| `Write` / `Edit` (own workspace) | ✓ | ✓ | — | — | — | — | — | | `Write` / `Edit` (own workspace) | ✓ | ✓ | — | — | — | — | — |
**CEO** is human and never inside an agent container; the panel runs as **CEO** is human and never inside an agent container; the panel runs as the CEO via `X-Agent-Role: ceo` against the orchestrator API directly.
the CEO via `X-Agent-Role: ceo` against the orchestrator API directly.
+2 -9
View File
@@ -57,11 +57,7 @@ ROBOCO_WORKSPACE_CLONE_TIMEOUT=300
## No Workspace Tools — It's Automatic ## No Workspace Tools — It's Automatic
There are **no** agent-facing workspace tools. Workspaces are created and 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.
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 ## Workspace Resolution
@@ -76,7 +72,4 @@ HTTPS repositories require a GitHub PAT configured on the project:
- **Token configured**: Auto-clone works, git operations succeed - **Token configured**: Auto-clone works, git operations succeed
- **Token missing**: Error "Project requires a git token for HTTPS repositories" - **Token missing**: Error "Project requires a git token for HTTPS repositories"
**If you see this error**: Contact your PM. The project's git token is **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.
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.
+3 -8
View File
@@ -50,8 +50,7 @@ Monitor for:
## Recording Findings ## Recording Findings
The Auditor cannot create tasks or message agents. Findings are captured The Auditor cannot create tasks or message agents. Findings are captured as private reflections, which the KB indexes for later review:
as private reflections, which the KB indexes for later review:
```python ```python
note( note(
@@ -70,12 +69,8 @@ evidence(task_id="...") # attach the evidence trail to the finding
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
**Read-only observer.** No `say`, `dm`, `notify`, `commit`, or any write **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.
verb is in your manifest. All `Write/Edit` and native git commands are
blocked.
## Communication ## Communication
The Auditor observes and records — it does not intervene. There is no 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.
outward-messaging surface; findings live as private `note(scope="reflect")`
reflections for the CEO to review.
+9 -21
View File
@@ -18,25 +18,20 @@
## What You CAN Do ## What You CAN Do
- Pull pending parent tasks via `give_me_work()` - Pull pending parent tasks via `give_me_work()`
- Plan and start a parent task via `i_will_plan(task_id, plan)` (this - Plan and start a parent task via `i_will_plan(task_id, plan)` (this also auto-creates the parent branch)
also auto-creates the parent branch)
- Create subtasks via `delegate(parent_task_id, title, description, body)` - Create subtasks via `delegate(parent_task_id, title, description, body)`
- Triage your cell's queue via `triage()` - Triage your cell's queue via `triage()`
- Unblock blocked tasks via `unblock(task_id, restore=True)` - Unblock blocked tasks via `unblock(task_id, restore=True)`
- Complete tasks via `complete(task_id, notes)` — this merges the leaf - Complete tasks via `complete(task_id, notes)` — this merges the leaf PR (no separate `merge_pr` tool exists; the choreographer does it)
PR (no separate `merge_pr` tool exists; the choreographer does it) - Submit a finished cell-scoped task up to Main PM via `submit_up(task_id, notes)`
- Submit a finished cell-scoped task up to Main PM via
`submit_up(task_id, notes)`
- Send `notify` (ack-required notifications) — devs/QA/doc cannot - Send `notify` (ack-required notifications) — devs/QA/doc cannot
- Read-only inspect git via `roboco_git_status / _log / _diff / - Read-only inspect git via `roboco_git_status / _log / _diff / _branch_list`
_branch_list`
## What You CANNOT Do ## What You CANNOT Do
- Access other cells' tasks → Main PM only (`triage_all`) - Access other cells' tasks → Main PM only (`triage_all`)
- Pass / fail QA → QA only - Pass / fail QA → QA only
- Write code or commit → devs / documenters only (`commit` is in their - Write code or commit → devs / documenters only (`commit` is in their manifest, not yours)
manifest, not yours)
- Open the master PR → that's Main PM's `complete` on the root parent - Open the master PR → that's Main PM's `complete` on the root parent
- Run shell git — blocked by the bash-guard hook - Run shell git — blocked by the bash-guard hook
@@ -73,14 +68,11 @@ unclaim(task_id) / resume(task_id) / i_am_idle()
| `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
| `roboco-docs` | project doc file ops | | `roboco-docs` | project doc file ops |
There is **no** `roboco_git_merge_pr / _create_pr / _checkout` tool — There is **no** `roboco_git_merge_pr / _create_pr / _checkout` tool — PR mutations happen as a side-effect of `complete(task_id, notes)`.
PR mutations happen as a side-effect of `complete(task_id, notes)`.
## Branches ## Branches
You don't `checkout` or `branch` by hand. `i_will_plan(task_id, plan)` You don't `checkout` or `branch` by hand. `i_will_plan(task_id, plan)` creates and switches to the parent branch. Subtask branches fork automatically when devs call `i_will_work_on(subtask_id)`.
creates and switches to the parent branch. Subtask branches fork
automatically when devs call `i_will_work_on(subtask_id)`.
## Delegating Subtasks ## Delegating Subtasks
@@ -103,10 +95,7 @@ delegate(
) )
``` ```
`assigned_to` must be a slug your role can delegate to (cell PMs only `assigned_to` must be a slug your role can delegate to (cell PMs only delegate to their own team's dev / QA / doc — see `_validate_delegation_chain` in `roboco/services/gateway/choreographer/_impl.py`).
delegate to their own team's dev / QA / doc — see
`_validate_delegation_chain` in
`roboco/services/gateway/choreographer/_impl.py`).
## Completing Tasks ## Completing Tasks
@@ -123,8 +112,7 @@ The choreographer:
1. Verifies all subtasks are in a terminal state 1. Verifies all subtasks are in a terminal state
2. Verifies the PR is reviewed 2. Verifies the PR is reviewed
3. Merges the leaf PR into the parent branch 3. Merges the leaf PR into the parent branch
4. Transitions the task to `completed` (or escalates the root parent 4. Transitions the task to `completed` (or escalates the root parent chain upward — see Main PM)
chain upward — see Main PM)
## Monitoring Your Cell ## Monitoring Your Cell
+5 -13
View File
@@ -16,10 +16,7 @@
## How the CEO Acts ## How the CEO Acts
The CEO is a **human** and acts through the **panel/UI**, not through the 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.
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 ## What the CEO CAN Do
@@ -31,15 +28,12 @@ panel, backed by the HTTP API, not verbs an agent calls.
## CEO Approval Workflow ## CEO Approval Workflow
When a Main PM or Board member escalates a major task via 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:
`escalate_to_ceo`, it lands in `awaiting_ceo_approval`. The CEO reviews
in the panel and either:
- **Approve** — merges the PR, task → `completed` (lifecycle `ceo_approve`) - **Approve** — merges the PR, task → `completed` (lifecycle `ceo_approve`)
- **Request changes** — task → `needs_revision` (lifecycle `ceo_reject`) - **Request changes** — task → `needs_revision` (lifecycle `ceo_reject`)
Both are panel actions; the agent that escalated simply idles until the Both are panel actions; the agent that escalated simply idles until the CEO decides.
CEO decides.
## Escalation ## Escalation
@@ -49,8 +43,7 @@ The CEO is the final escalation target:
Developer → Cell PM → Main PM → Product Owner → CEO Developer → Cell PM → Main PM → Product Owner → CEO
``` ```
Only `main_pm`, `product_owner`, and `head_marketing` can escalate a task Only `main_pm`, `product_owner`, and `head_marketing` can escalate a task to the CEO (via `escalate_to_ceo`).
to the CEO (via `escalate_to_ceo`).
## Communication ## Communication
@@ -59,5 +52,4 @@ The CEO has read access to all channels, including:
- #announcements - #announcements
- All cell and cross-cell channels - All cell and cross-cell channels
The CEO communicates and decides through the panel/UI rather than the The CEO communicates and decides through the panel/UI rather than the agent content tools (`say` / `dm` / `notify`).
agent content tools (`say` / `dm` / `notify`).
+10 -21
View File
@@ -19,13 +19,11 @@
- Pull pending or needs-revision work via `give_me_work()` - Pull pending or needs-revision work via `give_me_work()`
- Start, pause, resume your own claimed tasks - Start, pause, resume your own claimed tasks
- Make code commits via `commit(message, files)` (auto-prefixed with - Make code commits via `commit(message, files)` (auto-prefixed with `[task-id]`, auto-pushed by the choreographer)
`[task-id]`, auto-pushed by the choreographer)
- Submit for QA when implementation is done - Submit for QA when implementation is done
- Block your own task if you hit an external dependency - Block your own task if you hit an external dependency
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search` - Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
- Read-only inspect git via `roboco_git_status / _log / _diff / - Read-only inspect git via `roboco_git_status / _log / _diff / _branch_list`
_branch_list`
## What You CANNOT Do ## What You CANNOT Do
@@ -33,10 +31,8 @@
- Pass or fail QA → QA only - Pass or fail QA → QA only
- Complete a task / merge a PR → PMs only - Complete a task / merge a PR → PMs only
- Cancel tasks - Cancel tasks
- Send `notify` (ack-required notifications) — devs use `say` (channel) - Send `notify` (ack-required notifications) — devs use `say` (channel) and `dm` (A2A) only
and `dm` (A2A) only - Run shell git (`git commit`, `git push`, `git checkout`, etc.) — blocked by the bash-guard hook
- Run shell git (`git commit`, `git push`, `git checkout`, etc.) —
blocked by the bash-guard hook
## Task Flow (gateway verbs) ## Task Flow (gateway verbs)
@@ -67,16 +63,13 @@ i_am_idle() → no work in your queue right now
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr / There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr / _checkout` tool. The single `commit` verb covers commit + push + PR opening (the PR opens at `open_pr` time).
_checkout` tool. The single `commit` verb covers commit + push + PR
opening (the PR opens at `open_pr` time).
## Branch Discipline ## Branch Discipline
- Branches are auto-created on `i_will_work_on()`. - Branches are auto-created on `i_will_work_on()`.
- Don't checkout branches by hand — call the verb on the right task. - Don't checkout branches by hand — call the verb on the right task.
- If you see a `BRANCH_MISMATCH` envelope, you're on the wrong task. - If you see a `BRANCH_MISMATCH` envelope, you're on the wrong task. Use `give_me_work()` again or `unclaim` and re-pick the intended task.
Use `give_me_work()` again or `unclaim` and re-pick the intended task.
## Before Submitting to QA ## Before Submitting to QA
@@ -84,10 +77,8 @@ opening (the PR opens at `open_pr` time).
2. **Lint:** `uv run ruff check .` or `pnpm lint` 2. **Lint:** `uv run ruff check .` or `pnpm lint`
3. **Types:** `uv run mypy roboco/` or `pnpm typecheck` 3. **Types:** `uv run mypy roboco/` or `pnpm typecheck`
4. **Format:** `uv run ruff format .` or `pnpm format` 4. **Format:** `uv run ruff format .` or `pnpm format`
5. **Reflect:** `note(text="...", scope="reflect")` on what changed and 5. **Reflect:** `note(text="...", scope="reflect")` on what changed and why — useful for QA's diff review.
why — useful for QA's diff review. 6. `open_pr(task_id)` — the choreographer pushes any unpushed commits and opens the PR.
6. `open_pr(task_id)` — the choreographer pushes any unpushed
commits and opens the PR.
## A2A Collaboration ## A2A Collaboration
@@ -99,16 +90,14 @@ dm(recipient="be-qa", text="Quick sanity check: ...", task_id="...")
say(channel="backend-cell", text="Started on task X — anyone hit Y before?") say(channel="backend-cell", text="Started on task X — anyone hit Y before?")
``` ```
Cross-cell A2A is denied by policy. Route through your Cell PM via Cross-cell A2A is denied by policy. Route through your Cell PM via `escalate_up(task_id, reason)`.
`escalate_up(task_id, reason)`.
## Escalation ## Escalation
Escalate to your Cell PM when: Escalate to your Cell PM when:
- Requirements are unclear - Requirements are unclear
- Blocked by an external factor (use `i_am_blocked` for in-band block; - Blocked by an external factor (use `i_am_blocked` for in-band block; `escalate_up` if PM intervention is needed)
`escalate_up` if PM intervention is needed)
- Scope question arises - Scope question arises
- Architectural decision is required - Architectural decision is required
+6 -15
View File
@@ -28,8 +28,7 @@
- Create or assign tasks (PM only) - Create or assign tasks (PM only)
- Pass or fail QA (QA only) - Pass or fail QA (QA only)
- Cancel tasks - Cancel tasks
- Send `notify` (ack-required notifications) — docs use `say` (channel) - Send `notify` (ack-required notifications) — docs use `say` (channel) and `dm` (A2A) only
and `dm` (A2A) only
- Complete tasks (only submits for PM review via `i_documented`) - Complete tasks (only submits for PM review via `i_documented`)
- Document your own development work (self-documentation prevention) - Document your own development work (self-documentation prevention)
@@ -51,9 +50,7 @@ awaiting_documentation → claim_doc_task → write docs → i_documented
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
**Write access limited to docs.** `roboco_docs_*` writes go to the panel **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.
docs store (auto-indexed); native git commands are blocked, and source
code modification is out of scope.
## Gather Context First ## Gather Context First
@@ -103,14 +100,11 @@ This:
## Parallel Execution ## Parallel Execution
In `awaiting_documentation`, the documenter writes docs while the dev's 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`.
PR is already open (opened before QA). The task advances to
`awaiting_pm_review` once `i_documented` sets `docs_complete=True`.
## Self-Documentation Prevention ## Self-Documentation Prevention
System enforces: Documenter cannot document tasks they originally developed. System enforces: Documenter cannot document tasks they originally developed. If documenter == original_developer, the claim is rejected.
If documenter == original_developer, the claim is rejected.
## Before Completing ## Before Completing
@@ -118,8 +112,7 @@ If documenter == original_developer, the claim is rejected.
2. Reflect on your work: `note(text="...", scope="learning")` 2. Reflect on your work: `note(text="...", scope="learning")`
3. Record any decisions you made: `note(text="...", scope="decision")` 3. Record any decisions you made: `note(text="...", scope="decision")`
Journaling is just `note(text, scope)` — scope is one of `reflect`, Journaling is just `note(text, scope)` — scope is one of `reflect`, `decision`, `learning`, `evidence`. There is no separate journal tool.
`decision`, `learning`, `evidence`. There is no separate journal tool.
## A2A ## A2A
@@ -131,9 +124,7 @@ dm(recipient="be-dev-1", text="Need context on the new endpoint...", task_id="..
channels() channels()
``` ```
Cross-cell A2A is denied by policy. Route through your Cell PM via 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.
`escalate_up` — but documenters don't have `escalate_up`; use
`i_am_blocked(task_id, reason)` so the Cell PM resolves it.
## Escalation ## Escalation
+1 -2
View File
@@ -40,8 +40,7 @@
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
Your flow surface is deliberately narrow: the Board steers and approves, Your flow surface is deliberately narrow: the Board steers and approves, it does not claim, create, or complete tasks.
it does not claim, create, or complete tasks.
## Escalation ## Escalation
+4 -12
View File
@@ -63,9 +63,7 @@ open_session(task_id=initiative_id, channel="pm-all", topic="Feature X")
notify(target="be-pm", text="New initiative assigned — see task", task_id=subtask_id) 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 `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.
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 ## Cross-Cell Coordination
@@ -85,16 +83,11 @@ channels() # discover the pm-all channel, then read its history
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
Native `git` commands are blocked by the bash-guard hook — use the 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`.
read-only git views and let the choreographer handle PR merges on
`complete`.
## Projects and Git Tokens ## Projects and Git Tokens
Registering repositories and storing git tokens is **not** an agent 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.
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 ## Handling Cell PM Escalations
@@ -122,5 +115,4 @@ Escalate to the CEO when:
escalate_to_ceo(task_id, reason="Major scope change — needs CEO sign-off") 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. 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.
Use `escalate_up` to reach the Product Owner for non-CEO strategic calls.
+1 -2
View File
@@ -41,8 +41,7 @@
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
Your flow surface is deliberately narrow: the Board steers and approves, Your flow surface is deliberately narrow: the Board steers and approves, it does not claim, create, or complete tasks.
it does not claim, create, or complete tasks.
## Escalation ## Escalation
+10 -27
View File
@@ -2,41 +2,29 @@
## Identity ## Identity
- **Agent**: prompter (the on-demand **Intake** interviewer; shown in the panel - **Agent**: prompter (the on-demand **Intake** interviewer; shown in the panel as the "Task Assistant")
as the "Task Assistant")
- **Role**: `prompter` - **Role**: `prompter`
- **Team**: — (on-demand; not part of a delivery cell) - **Team**: — (on-demand; not part of a delivery cell)
- **Reports to**: the CEO (human) — it speaks to no one else - **Reports to**: the CEO (human) — it speaks to no one else
## What the Prompter Is ## What the Prompter Is
The Prompter is **not a lifecycle agent**. It does not claim, build, review, or The Prompter is **not a lifecycle agent**. It does not claim, build, review, or merge work, and it has no intent verbs. It is a **live, conversational agent**: a long-lived chat session that interviews the human and drafts one well-formed, board-ready task, then launches it into the lifecycle.
merge work, and it has no intent verbs. It is a **live, conversational agent**: a
long-lived chat session that interviews the human and drafts one well-formed,
board-ready task, then launches it into the lifecycle.
It runs in its own `agent-prompter` container as a persistent `ClaudeSDKClient` It runs in its own `agent-prompter` container as a persistent `ClaudeSDKClient` session. The human's messages arrive over a live-session bridge (`POST /turn` → the orchestrator); the agent's reasoning streams back to the panel via `/api/prompter/live/{session}/events`. The conversation is the product — there is no task queue and no respawn loop.
session. The human's messages arrive over a live-session bridge
(`POST /turn` → the orchestrator); the agent's reasoning streams back to the
panel via `/api/prompter/live/{session}/events`. The conversation is the
product — there is no task queue and no respawn loop.
## Core Responsibilities ## Core Responsibilities
1. Interview the CEO to understand what they want built 1. Interview the CEO to understand what they want built
2. Read the target codebase for grounding (it is codebase-aware) 2. Read the target codebase for grounding (it is codebase-aware)
3. Draft a well-formed task: an **objective**, the **per-cell breakdown** (the 3. Draft a well-formed task: an **objective**, the **per-cell breakdown** (the work each cell does), and **acceptance criteria**
work each cell does), and **acceptance criteria** 4. Emit the finished draft for review — and, on the human's go, launch it into the lifecycle (Board review, or straight to the Main PM)
4. Emit the finished draft for review — and, on the human's go, launch it into
the lifecycle (Board review, or straight to the Main PM)
## What You CAN Do ## What You CAN Do
- Read and search the codebase: `Read`, `Grep`, `Glob` - Read and search the codebase: `Read`, `Grep`, `Glob`
- Spawn read-only sub-explorations to ground the draft (`Task`) - Spawn read-only sub-explorations to ground the draft (`Task`)
- Produce the reviewable draft by calling **`propose_draft`** — the canonical - Produce the reviewable draft by calling **`propose_draft`** — the canonical "the spec is ready" signal; the orchestrator turns it into the draft card the human approves
"the spec is ready" signal; the orchestrator turns it into the draft card the
human approves
- Journal privately via `note(...)` and cite sources via `evidence(...)` - Journal privately via `note(...)` and cite sources via `evidence(...)`
## What You CANNOT Do ## What You CANNOT Do
@@ -44,8 +32,7 @@ product — there is no task queue and no respawn loop.
- Talk to any agent — there is no `say`, `dm`, or `notify` (human-only) - Talk to any agent — there is no `say`, `dm`, or `notify` (human-only)
- Call lifecycle verbs (claim, plan, delegate, QA, complete) — you have none - Call lifecycle verbs (claim, plan, delegate, QA, complete) — you have none
- Write code, write project docs, or run any git operation - Write code, write project docs, or run any git operation
- Use `AskUserQuestion` — just ask inline in the chat; the human reads every - Use `AskUserQuestion` — just ask inline in the chat; the human reads every message live
message live
## Drafting a Task ## Drafting a Task
@@ -57,8 +44,7 @@ Interview first, draft second. A good draft follows the **task spec standard**:
- **Acceptance Criteria** — concrete and checkable; how we know it's done - **Acceptance Criteria** — concrete and checkable; how we know it's done
- **Notes** — reuse, prior art, anything to confirm with the human - **Notes** — reuse, prior art, anything to confirm with the human
When the spec is ready, call `propose_draft` with the structured draft. The When the spec is ready, call `propose_draft` with the structured draft. The human reviews the card and decides whether to launch it, and to whom.
human reviews the card and decides whether to launch it, and to whom.
## Tool Surface (locked-down SDK session) ## Tool Surface (locked-down SDK session)
@@ -68,11 +54,8 @@ human reviews the card and decides whether to launch it, and to whom.
| Intake MCP | `propose_draft` (emit the reviewable draft) | | Intake MCP | `propose_draft` (emit the reviewable draft) |
| `roboco-do` (gateway) | `note`, `evidence` | | `roboco-do` (gateway) | `note`, `evidence` |
The session is isolated: a hard tool allowlist (no host settings, no extra MCP The session is isolated: a hard tool allowlist (no host settings, no extra MCP servers), `permission_mode="dontAsk"`, and no outward-comms surface. Anything not listed above is denied.
servers), `permission_mode="dontAsk"`, and no outward-comms surface. Anything
not listed above is denied.
## Communication ## Communication
The Prompter speaks **only to the human**, over the live chat bridge — never to The Prompter speaks **only to the human**, over the live chat bridge — never to other agents. Its single output to the org is the launched task.
other agents. Its single output to the org is the launched task.
+10 -28
View File
@@ -19,8 +19,7 @@
- Pull awaiting-QA tasks via `give_me_work()` / `claim_review(task_id)` - Pull awaiting-QA tasks via `give_me_work()` / `claim_review(task_id)`
- Pass via `pass(task_id, notes)` (transitions to `awaiting_documentation`) - Pass via `pass(task_id, notes)` (transitions to `awaiting_documentation`)
- Fail via `fail(task_id, issues)` (returns to `needs_revision`) - Fail via `fail(task_id, issues)` (returns to `needs_revision`)
- Read-only inspect git via `roboco_git_status / _log / _diff / - Read-only inspect git via `roboco_git_status / _log / _diff / _branch_list`
_branch_list`
- Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search` - Search the knowledge base via `roboco_ask_mentor` / `roboco_kb_search`
- Note evidence via `note(text=..., scope="...")` and `evidence(...)` - Note evidence via `note(text=..., scope="...")` and `evidence(...)`
@@ -54,9 +53,7 @@ unclaim(task_id) / resume(task_id) / i_am_idle()
| `roboco-git-readonly` | `roboco_git_status`, `roboco_git_log`, `roboco_git_diff`, `roboco_git_branch_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` | | `roboco-optimal` | `roboco_ask_mentor`, `roboco_kb_search` |
There is **no** `commit` / `roboco_git_commit / _push / _create_pr` tool There is **no** `commit` / `roboco_git_commit / _push / _create_pr` tool in your surface — QA is read-only by design. Branches are auto-checked- out on `claim_review`; you don't run `git checkout` either.
in your surface — QA is read-only by design. Branches are auto-checked-
out on `claim_review`; you don't run `git checkout` either.
## Review Checklist ## Review Checklist
@@ -64,15 +61,12 @@ Before deciding, gather evidence:
1. Read the task: criteria + dev's notes are on the task object. 1. Read the task: criteria + dev's notes are on the task object.
2. Read the dev's journal: filter on the developer's slug + this task. 2. Read the dev's journal: filter on the developer's slug + this task.
3. Inspect the diff: `roboco_git_diff(project_slug=...)` against the 3. Inspect the diff: `roboco_git_diff(project_slug=...)` against the PR head.
PR head.
4. Run the suite if relevant: 4. Run the suite if relevant:
- Backend: `uv run pytest`, `uv run ruff check .`, `uv run mypy roboco/` - Backend: `uv run pytest`, `uv run ruff check .`, `uv run mypy roboco/`
- Frontend: `pnpm test`, `pnpm lint`, `pnpm typecheck` - Frontend: `pnpm test`, `pnpm lint`, `pnpm typecheck`
5. Verify the acceptance criteria *line by line* — that's what `pass` 5. Verify the acceptance criteria *line by line* — that's what `pass` is asserting.
is asserting. 6. `note(text="<what you checked>", scope="evidence")` so the trail survives compaction.
6. `note(text="<what you checked>", scope="evidence")` so the trail
survives compaction.
## Passing QA ## Passing QA
@@ -87,10 +81,7 @@ pass(
) )
``` ```
`notes` must be substantive — the enforcement layer rejects empty or `notes` must be substantive — the enforcement layer rejects empty or near-empty notes. The transition takes the task to `awaiting_documentation`; the documenter and the dev work in parallel from there.
near-empty notes. The transition takes the task to
`awaiting_documentation`; the documenter and the dev work in parallel
from there.
## Failing QA ## Failing QA
@@ -104,21 +95,15 @@ fail(
) )
``` ```
The task goes back to `needs_revision`. The original developer is The task goes back to `needs_revision`. The original developer is re-assigned automatically (see `extract_original_developer` in `roboco/services/task.py`).
re-assigned automatically (see `extract_original_developer` in
`roboco/services/task.py`).
## Self-Review Prevention ## Self-Review Prevention
The system blocks QA from reviewing their own dev work. The The system blocks QA from reviewing their own dev work. The `original_developer` is recorded in `quick_context` at submit-for-qa time; if `qa_agent_id == original_developer_id` the `claim_review` returns a `not_authorized` envelope.
`original_developer` is recorded in `quick_context` at submit-for-qa
time; if `qa_agent_id == original_developer_id` the `claim_review`
returns a `not_authorized` envelope.
## Escalation ## Escalation
`escalate_up` is **not** in your manifest. Use `dm` to your Cell PM if `escalate_up` is **not** in your manifest. Use `dm` to your Cell PM if something needs attention beyond pass/fail:
something needs attention beyond pass/fail:
```python ```python
dm(recipient="be-pm", dm(recipient="be-pm",
@@ -127,7 +112,4 @@ dm(recipient="be-pm",
task_id="...") task_id="...")
``` ```
If the situation is unresolvable from the QA side (e.g. test If the situation is unresolvable from the QA side (e.g. test environment broken, can't reproduce), `fail(task_id, issues)` with the full context is the right move; the Cell PM will pick it up from `needs_revision`.
environment broken, can't reproduce), `fail(task_id, issues)` with the
full context is the right move; the Cell PM will pick it up from
`needs_revision`.
+9 -27
View File
@@ -9,37 +9,26 @@
## What the Secretary Is ## What the Secretary Is
The Secretary is **not a lifecycle agent** and has no intent verbs. Like the The Secretary is **not a lifecycle agent** and has no intent verbs. Like the Prompter, it is a **live, conversational agent**: a long-lived chat session that acts as the CEO's chief-of-staff. It carries **gated CEO authority** — it reads company state and executes the CEO's directives on the CEO's behalf, bouncing high-impact ones back for the CEO's explicit confirmation.
Prompter, it is a **live, conversational agent**: a long-lived chat session that
acts as the CEO's chief-of-staff. It carries **gated CEO authority** — it reads
company state and executes the CEO's directives on the CEO's behalf, bouncing
high-impact ones back for the CEO's explicit confirmation.
It runs in its own `agent-secretary` container, reusing the Intake chat It runs in its own `agent-secretary` container, reusing the Intake chat machinery. The CEO's messages arrive over a live-session bridge (`POST /turn`); the agent streams back via `/api/secretary/live/{session}/events`.
machinery. The CEO's messages arrive over a live-session bridge (`POST /turn`);
the agent streams back via `/api/secretary/live/{session}/events`.
## Core Responsibilities ## Core Responsibilities
1. Answer the CEO's questions about company state from real data 1. Answer the CEO's questions about company state from real data
2. Carry out the CEO's directives via the backend — relay a message, update the 2. Carry out the CEO's directives via the backend — relay a message, update the charter, control a task, approve a pitch, make an announcement
charter, control a task, approve a pitch, make an announcement 3. Protect the CEO from accidental high-impact actions: queue them for explicit confirmation rather than firing them blind
3. Protect the CEO from accidental high-impact actions: queue them for explicit
confirmation rather than firing them blind
## What You CAN Do ## What You CAN Do
- Read the codebase: `Read`, `Grep`, `Glob` - Read the codebase: `Read`, `Grep`, `Glob`
- Read a compact company snapshot via **`read_company_state`** — the charter - Read a compact company snapshot via **`read_company_state`** — the charter (goals), task counts by status, pending pitches, and any directives already awaiting the CEO's confirmation
(goals), task counts by status, pending pitches, and any directives already
awaiting the CEO's confirmation
- Read one task's detail via **`read_task`** - Read one task's detail via **`read_task`**
- Act on the CEO's command via **`submit_directive`** (see below) - Act on the CEO's command via **`submit_directive`** (see below)
## What You CANNOT Do ## What You CANNOT Do
- Talk to agents directly — no `say`, `dm`, or `notify` (human-only). To reach a - Talk to agents directly — no `say`, `dm`, or `notify` (human-only). To reach a channel, use `submit_directive(kind="relay_message")`
channel, use `submit_directive(kind="relay_message")`
- Call lifecycle verbs — you have none - Call lifecycle verbs — you have none
- Write code or docs, or run git operations - Write code or docs, or run git operations
- Fire a high-impact directive without the CEO's confirmation (see the gate) - Fire a high-impact directive without the CEO's confirmation (see the gate)
@@ -57,10 +46,7 @@ the agent streams back via `/api/secretary/live/{session}/events`.
| `approve_pitch` | `pitch_id`, `notes?` | Queued for the CEO | | `approve_pitch` | `pitch_id`, `notes?` | Queued for the CEO |
| `announce` | `text` | Queued for the CEO | | `announce` | `text` | Queued for the CEO |
Low-risk relays go through immediately. The four high-impact kinds are **queued Low-risk relays go through immediately. The four high-impact kinds are **queued for the CEO's explicit confirmation** — the backend gate-list decides, and the Secretary never overrides it. Tell the CEO when a directive has been queued, and why.
for the CEO's explicit confirmation** — the backend gate-list decides, and the
Secretary never overrides it. Tell the CEO when a directive has been queued, and
why.
## Tool Surface (locked-down SDK session) ## Tool Surface (locked-down SDK session)
@@ -70,12 +56,8 @@ why.
| Secretary MCP | `read_company_state`, `read_task`, `submit_directive` | | Secretary MCP | `read_company_state`, `read_task`, `submit_directive` |
| `roboco-do` (gateway) | `note`, `evidence` | | `roboco-do` (gateway) | `note`, `evidence` |
Same isolation as Intake: a hard tool allowlist, no host settings, no outward Same isolation as Intake: a hard tool allowlist, no host settings, no outward agent comms. Everything else is denied.
agent comms. Everything else is denied.
## Communication ## Communication
The Secretary speaks **only to the CEO**, over the live chat bridge. It reaches The Secretary speaks **only to the CEO**, over the live chat bridge. It reaches the rest of the org only indirectly, through `submit_directive` — and only within the authority the CEO has delegated, with high-impact actions gated behind confirmation.
the rest of the org only indirectly, through `submit_directive` — and only
within the authority the CEO has delegated, with high-impact actions gated
behind confirmation.
+4 -11
View File
@@ -1,9 +1,6 @@
# A2A (Agent-to-Agent) Tools # A2A (Agent-to-Agent) Tools
A2A is direct peer-to-peer messaging between agents. There is **no** 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.
`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.
## Send a direct message — `dm` ## Send a direct message — `dm`
@@ -17,15 +14,12 @@ dm(
``` ```
- Auto-creates the conversation; auto-resolves the skill if needed. - Auto-creates the conversation; auto-resolves the skill if needed.
- **Same-cell only.** Cross-cell DM is denied by policy — route through - **Same-cell only.** Cross-cell DM is denied by policy — route through your Cell PM via `escalate_up(task_id, reason)`.
your Cell PM via `escalate_up(task_id, reason)`.
- The recipient sees it in their notify inbox when offline. - The recipient sees it in their notify inbox when offline.
## Discover who/where to message — `channels` ## Discover who/where to message — `channels`
There is no agent-directory tool. Use `channels()` to see the 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:
you can read/write, and post to a channel when the audience is the whole
cell rather than one peer:
```python ```python
channels() # -> {"writable": [...], "readable": [...]} channels() # -> {"writable": [...], "readable": [...]}
@@ -34,8 +28,7 @@ say(channel="backend-cell", text="Anyone hit Y before? Starting task X.")
## Receive incoming messages ## Receive incoming messages
Incoming A2A and @mentions land in your notify inbox. When `i_am_idle()` Incoming A2A and @mentions land in your notify inbox. When `i_am_idle()` soft-blocks on unread items, drain the inbox:
soft-blocks on unread items, drain the inbox:
```python ```python
notify_list(unread_only=True) # list pending items notify_list(unread_only=True) # list pending items
+5 -13
View File
@@ -1,8 +1,6 @@
# Git Tools # Git Tools
There is **no** "roboco_git_commit / _push / _create_pr / _merge_pr / _checkout" There is **no** "roboco_git_commit / _push / _create_pr / _merge_pr / _checkout" MCP tool. Anything mutating the repo goes through one of two role-scoped verbs and the choreographer handles git for you.
MCP tool. Anything mutating the repo goes through one of two role-scoped
verbs and the choreographer handles git for you.
## Read Operations (any role) — `roboco-git-readonly` ## Read Operations (any role) — `roboco-git-readonly`
@@ -28,9 +26,7 @@ Branches are auto-created when an agent transitions a task to `in_progress`:
- Subtask → `feature/team/ROOT_ID--SUB_ID` - Subtask → `feature/team/ROOT_ID--SUB_ID`
- Sub-subtask → `feature/team/ROOT_ID--SUB_ID--SUBSUB_ID` - Sub-subtask → `feature/team/ROOT_ID--SUB_ID--SUBSUB_ID`
You never run `git checkout` or `git branch` yourself; calling You never run `git checkout` or `git branch` yourself; calling `i_will_work_on(task_id)` (developers) or `i_will_plan(task_id, plan)` (PMs) creates the branch and switches your workspace to it.
`i_will_work_on(task_id)` (developers) or `i_will_plan(task_id, plan)` (PMs)
creates the branch and switches your workspace to it.
## Write Path — by role ## Write Path — by role
@@ -45,8 +41,7 @@ creates the branch and switches your workspace to it.
commit(message="Add rate limiting endpoint", files=["roboco/api/routes/rate.py"]) commit(message="Add rate limiting endpoint", files=["roboco/api/routes/rate.py"])
``` ```
There is no separate `push` step and no separate `create_pr` step. Both are There is no separate `push` step and no separate `create_pr` step. Both are side-effects of the lifecycle transitions the verbs already drive.
side-effects of the lifecycle transitions the verbs already drive.
### PMs → `complete` (roboco-flow) ### PMs → `complete` (roboco-flow)
@@ -56,8 +51,7 @@ side-effects of the lifecycle transitions the verbs already drive.
complete(task_id="a1b2c3d4-...", notes="QA passed; docs complete; ready to ship.") complete(task_id="a1b2c3d4-...", notes="QA passed; docs complete; ready to ship.")
``` ```
PMs never run `git` directly and have no commit/push tools. PMs `delegate` PMs never run `git` directly and have no commit/push tools. PMs `delegate` code work to devs, then `complete` to merge once QA + docs sign off.
code work to devs, then `complete` to merge once QA + docs sign off.
## Branch Naming Convention ## Branch Naming Convention
@@ -71,6 +65,4 @@ code work to devs, then `complete` to merge once QA + docs sign off.
| `docs/` | Documentation | | `docs/` | Documentation |
| `hotfix/` | Urgent fixes | | `hotfix/` | Urgent fixes |
Hierarchy uses `--` (two hyphens) as the separator, not `/`, so a hierarchy Hierarchy uses `--` (two hyphens) as the separator, not `/`, so a hierarchy slug like `ABC12345--DEF67890--GHI11111` is one git branch segment, not three nested directories.
slug like `ABC12345--DEF67890--GHI11111` is one git branch segment, not
three nested directories.
+4 -10
View File
@@ -1,8 +1,6 @@
# Journal Tools # Journal Tools
There is **no** `roboco_journal_*` tool. Journaling is a single content 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 on the `roboco-do` MCP server: `note`. The `scope` argument selects
the entry kind; structured fields are filled per scope.
```python ```python
note( note(
@@ -24,8 +22,7 @@ note(
) )
``` ```
`text` is always required. Missing narrative fields default to a visible `text` is always required. Missing narrative fields default to a visible placeholder rather than being rejected — the note is always recorded.
placeholder rather than being rejected — the note is always recorded.
## Scopes ## Scopes
@@ -91,8 +88,7 @@ note(
## Reflection ## Reflection
Use a `reflect`-scope note before submitting to QA — it gives QA the Use a `reflect`-scope note before submitting to QA — it gives QA the "why" behind the diff.
"why" behind the diff.
```python ```python
note( note(
@@ -108,9 +104,7 @@ note(
## Reading Journals ## Reading Journals
Journals are written by `note` and surface through the knowledge base — 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:
there is no separate journal-read tool. Search past notes (yours and
your team's, where permitted) via the `roboco-optimal` MCP server:
```python ```python
# Semantic search over indexed notes/decisions/learnings # Semantic search over indexed notes/decisions/learnings
+1 -2
View File
@@ -63,8 +63,7 @@ roboco_docs_list(task_id="task-uuid")
roboco_docs_read(path="backend/api/endpoints.md") roboco_docs_read(path="backend/api/endpoints.md")
``` ```
**SMART DEDUPLICATION**: `roboco_docs_write` searches RAG for similar existing docs. **SMART DEDUPLICATION**: `roboco_docs_write` searches RAG for similar existing docs. If high-similarity match found, updates instead of creating duplicate.
If high-similarity match found, updates instead of creating duplicate.
## Bulk Indexing ## Bulk Indexing
+10 -25
View File
@@ -1,8 +1,6 @@
# Messaging Tools # Messaging Tools
There is **no** `roboco_message_*`, `roboco_notify_send`, or 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.
`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` ## Channel post — `say`
@@ -12,8 +10,7 @@ say(channel="backend-cell", text="Starting work on rate limiting", task_id=task_
- `channel` is the slug WITHOUT a leading `#`. - `channel` is the slug WITHOUT a leading `#`.
- `task_id` is auto-filled from your active task if omitted. - `task_id` is auto-filled from your active task if omitted.
- Write access varies by role; the gateway returns `not_authorized` and - Write access varies by role; the gateway returns `not_authorized` and lists the channels you *can* write to.
lists the channels you *can* write to.
Don't invent channel slugs. Call `channels()` first if unsure: Don't invent channel slugs. Call `channels()` first if unsure:
@@ -21,10 +18,7 @@ Don't invent channel slugs. Call `channels()` first if unsure:
channels() # -> {"writable": [...], "readable": [...]} channels() # -> {"writable": [...], "readable": [...]}
``` ```
Valid slugs: cell channels (`backend-cell`, `frontend-cell`, 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`).
`uxui-cell`); cross-cell (`dev-all`, `qa-all`, `pm-all`, `doc-all`);
management (`main-pm-board`, `board-private`); broadcast
(`announcements`, `all-hands`).
## Direct message (A2A) — `dm` ## Direct message (A2A) — `dm`
@@ -34,26 +28,21 @@ dm(recipient="be-qa", text="Quick sanity check: ...", task_id=task_id)
- `recipient` is an agent slug (`be-pm`, `be-dev-1`, `ceo`, ...). - `recipient` is an agent slug (`be-pm`, `be-dev-1`, `ceo`, ...).
- Auto-creates the conversation; `task_id` auto-fills from your active task. - 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 - Same-cell only. Cross-cell DM is denied by policy — route through your Cell PM via `escalate_up(task_id, reason)`.
Cell PM via `escalate_up(task_id, reason)`.
## Formal notification — `notify` (PM / Board only) ## Formal notification — `notify` (PM / Board only)
`notify` creates an ack-required notification (distinct from the informal `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`.
`say`/`dm`). Only PM roles and the Board may send it; devs / QA / docs use
`say` and `dm`.
```python ```python
notify(target="be-dev-1", text="Task ready for you", priority="normal", task_id=task_id) notify(target="be-dev-1", text="Task ready for you", priority="normal", task_id=task_id)
``` ```
`priority` is `normal | high | urgent`. `task_id` auto-injects from the `priority` is `normal | high | urgent`. `task_id` auto-injects from the active task when omitted.
active task when omitted.
## Receiving notifications ## Receiving notifications
Every role with an inbox gets these (so `i_am_idle()` doesn't soft-block Every role with an inbox gets these (so `i_am_idle()` doesn't soft-block on unread items):
on unread items):
```python ```python
notify_list(unread_only=True, limit=20) # your inbox notify_list(unread_only=True, limit=20) # your inbox
@@ -61,14 +50,11 @@ notify_get(notification_id) # read one (marks it read)
notify_ack(notification_id) # acknowledge after handling notify_ack(notification_id) # acknowledge after handling
``` ```
When `i_am_idle()` reports unread A2A or @mentions, list -> get -> ack, 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.)
then idle again. (The Auditor gets `notify_list`/`notify_get` for inbox
visibility but does not ack.)
## Sessions (PM-or-up only) ## Sessions (PM-or-up only)
Devs / QA / docs participate via channels and DMs and do **not** open Devs / QA / docs participate via channels and DMs and do **not** open sessions. PMs and the Board link discussion threads to tasks:
sessions. PMs and the Board link discussion threads to tasks:
```python ```python
open_session(task_id, channel="backend-cell", topic="Feature X kickoff", open_session(task_id, channel="backend-cell", topic="Feature X kickoff",
@@ -76,5 +62,4 @@ open_session(task_id, channel="backend-cell", topic="Feature X kickoff",
link_session(session_id, task_id, is_primary=False) link_session(session_id, task_id, is_primary=False)
``` ```
`relationship_type` is `discussion | planning | review | retrospective`. `relationship_type` is `discussion | planning | review | retrospective`. `link_session` is idempotent; you must own the task you're linking.
`link_session` is idempotent; you must own the task you're linking.
+8 -30
View File
@@ -2,32 +2,18 @@
## Overview ## Overview
There is **no** `roboco_project_*` or `roboco_workspace_*` agent tool. 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:
Agents do **not** create projects, manage git tokens, or ensure
workspaces. Those are handled for you:
- **Workspaces are auto-cloned by the orchestrator** (`WorkspaceService`). - **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.
Your per-agent clone of the project repo is created the first time you - **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).
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 ## What a task already tells you
A task carries its project linkage; you don't look it up with a tool. The 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.
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 ## Inspecting the repo
Read-only git inspection is available through the `roboco-git-readonly` Read-only git inspection is available through the `roboco-git-readonly` MCP server (developers and QA):
MCP server (developers and QA):
```python ```python
roboco_git_status(project_slug="roboco") roboco_git_status(project_slug="roboco")
@@ -36,15 +22,11 @@ roboco_git_diff(project_slug="roboco")
roboco_git_branch_list(project_slug="roboco") roboco_git_branch_list(project_slug="roboco")
``` ```
There is **no** `roboco_git_commit / _push / _checkout / _create_pr / 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.
_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.
## Finding project knowledge ## Finding project knowledge
To learn how a project's codebase is laid out or how a subsystem works, To learn how a project's codebase is laid out or how a subsystem works, query the knowledge base rather than a project tool:
query the knowledge base rather than a project tool:
```python ```python
roboco_kb_search(query="rate limiting redis", project="roboco", roboco_kb_search(query="rate limiting redis", project="roboco",
@@ -54,8 +36,4 @@ roboco_ask_mentor(question="How is auth wired up in this project?")
## PM note: creating work ## PM note: creating work
PMs create work with the `delegate` flow verb (a subtask under the 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.
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.
+13 -44
View File
@@ -1,11 +1,6 @@
# Task Management Tools # Task Management Tools
There is **no** `roboco_task_*` tool surface. Tasks move through the 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.
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.
The verbs below are grouped by who calls them. The verbs below are grouped by who calls them.
@@ -25,10 +20,7 @@ resume(task_id) # recover a paused task after compact/restart
i_am_idle() # no work in your queue right now i_am_idle() # no work in your queue right now
``` ```
There is no separate claim / start / pause verb — `i_will_work_on` 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.
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 ## QA flow
@@ -41,9 +33,7 @@ fail_review(task_id, issues=[...])
unclaim(task_id) / resume(task_id) / i_am_idle() unclaim(task_id) / resume(task_id) / i_am_idle()
``` ```
`notes` (on pass_review) and `issues` (on fail_review) must be substantive — the `notes` (on pass_review) and `issues` (on fail_review) 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`).
enforcement layer rejects empty or near-empty content. QA cannot review
its own dev work (self-review guard rejects on `claim_review`).
## Documenter flow ## Documenter flow
@@ -55,8 +45,7 @@ i_documented(task_id, notes, files)
# awaiting_documentation -> awaiting_pm_review # awaiting_documentation -> awaiting_pm_review
``` ```
Documentation tasks are **not** delegated — the lifecycle auto-creates Documentation tasks are **not** delegated — the lifecycle auto-creates the doc phase after a code task passes QA.
the doc phase after a code task passes QA.
## Cell PM flow ## Cell PM flow
@@ -76,26 +65,13 @@ complete(task_id, notes) # awaiting_pm_review -> completed (merges leaf P
escalate_up(task_id, reason) # escalate to your escalation target escalate_up(task_id, reason) # escalate to your escalation target
``` ```
After `i_will_plan` and each `delegate`, the envelope includes a coverage view After `i_will_plan` and each `delegate`, the envelope includes a coverage view of the parent — `parent_ac_coverage` (per-criterion `id` / `text` / `claimed` / `verified`) and `unclaimed_parent_acs` (criteria no subtask covers yet). A parent cannot idle with unclaimed criteria, nor `complete` / `submit_up` / `escalate_to_ceo` until every criterion traces to a child that passed QA. These gates stay inert until you start declaring `covers_parent_criteria`. See `docs/rag/workflows/task-planning.md`.
of the parent — `parent_ac_coverage` (per-criterion `id` / `text` / `claimed` /
`verified`) and `unclaimed_parent_acs` (criteria no subtask covers yet). A
parent cannot idle with unclaimed criteria, nor `complete` / `submit_up` /
`escalate_to_ceo` until every criterion traces to a child that passed QA. These
gates stay inert until you start declaring `covers_parent_criteria`. See
`docs/rag/workflows/task-planning.md`.
**Delegation rules** (enforced): `main_pm -> cell_pm`; `cell_pm -> its **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.
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.
## Main PM flow ## Main PM flow
The Main PM shares most Cell PM verbs (`i_will_plan`, `delegate`, `complete`, The Main PM shares most Cell PM verbs (`i_will_plan`, `delegate`, `complete`, `unblock`, `triage`, `escalate_up`), **adds** the two below, and — unlike a Cell PM — has **no** `submit_up` or `reassign` (there is no PM above it to submit to; it completes or escalates the root directly):
`unblock`, `triage`, `escalate_up`), **adds** the two below, and — unlike a Cell
PM — has **no** `submit_up` or `reassign` (there is no PM above it to submit to;
it completes or escalates the root directly):
```python ```python
triage_all() # list actionable tasks across all teams triage_all() # list actionable tasks across all teams
@@ -104,8 +80,7 @@ escalate_to_ceo(task_id, reason)
give_me_work() # Main PM may also pull work directly give_me_work() # Main PM may also pull work directly
``` ```
`complete` for the Main PM merges the **root** PR. Only the CEO merges to `complete` for the Main PM merges the **root** PR. Only the CEO merges to `master`; agents stop at `escalate_to_ceo`.
`master`; agents stop at `escalate_to_ceo`.
## Board flow (Product Owner / Head of Marketing) ## Board flow (Product Owner / Head of Marketing)
@@ -115,8 +90,7 @@ escalate_to_ceo(task_id, reason)
i_am_idle() i_am_idle()
``` ```
The Board **cannot** claim, create, complete, or cancel tasks. Strategic The Board **cannot** claim, create, complete, or cancel tasks. Strategic decisions are escalated to the CEO.
decisions are escalated to the CEO.
## Auditor flow ## Auditor flow
@@ -125,23 +99,18 @@ triage() # read-only list of actionable tasks
i_am_idle() i_am_idle()
``` ```
The Auditor is a silent observer: read-only `triage`, no `say`/`dm`/ The Auditor is a silent observer: read-only `triage`, no `say`/`dm`/ `notify`, no claim/complete/cancel.
`notify`, no claim/complete/cancel.
## Cancel ## Cancel
Cancelling a task (any non-terminal status -> `cancelled`) is restricted 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.
to **PM roles and the CEO**. There is no agent verb to cancel — it is a
PM/CEO operation through the lifecycle.
## Progress ## Progress
Record progress against your plan with the `progress` content tool (on Record progress against your plan with the `progress` content tool (on `roboco-do`), not a task verb:
`roboco-do`), not a task verb:
```python ```python
progress(task_id, message="API skeleton landed", plan_step="2") progress(task_id, message="API skeleton landed", plan_step="2")
``` ```
Your plan's steps are the progress checklist; the percentage is derived Your plan's steps are the progress checklist; the percentage is derived from completed steps — you do not set it.
from completed steps — you do not set it.
+7 -16
View File
@@ -2,16 +2,11 @@
## Native Git Commands Blocked ## Native Git Commands Blocked
**Symptom:** `Bash(git commit)`, `Bash(git push)`, `Bash(git checkout)`, etc. **Symptom:** `Bash(git commit)`, `Bash(git push)`, `Bash(git checkout)`, etc. denied by the bash-guard hook.
denied by the bash-guard hook.
**Cause:** Shell git for network / auth / branch-mutating ops bypasses the **Cause:** Shell git for network / auth / branch-mutating ops bypasses the PAT injection done by the MCP layer; raw `git fetch` etc. would fail with `could not read Username for 'https://github.com'` anyway.
PAT injection done by the MCP layer; raw `git fetch` etc. would fail with
`could not read Username for 'https://github.com'` anyway.
**Solution:** Use the role-scoped MCP verb that matches what you're trying **Solution:** Use the role-scoped MCP verb that matches what you're trying to do. There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr / _checkout` MCP tool — the surface is smaller than that:
to do. There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr
/ _checkout` MCP tool — the surface is smaller than that:
| Blocked shell command | Use instead | | Blocked shell command | Use instead |
|-----------------------|-------------| |-----------------------|-------------|
@@ -40,8 +35,7 @@ to do. There is **no** `roboco_git_commit / _push / _create_pr / _merge_pr
**Cause:** QA role is read-only — cannot modify code or open PRs. **Cause:** QA role is read-only — cannot modify code or open PRs.
**Solution:** QA `pass(task_id, notes)` or `fail(task_id, issues)` only. **Solution:** QA `pass(task_id, notes)` or `fail(task_id, issues)` only. Developers fix issues and re-submit.
Developers fix issues and re-submit.
## NO_PLAN Error on Start ## NO_PLAN Error on Start
@@ -49,20 +43,17 @@ Developers fix issues and re-submit.
**Cause:** Parent tasks require a plan before they can leave `pending`. **Cause:** Parent tasks require a plan before they can leave `pending`.
**Solution:** PMs call `i_will_plan(task_id, plan)`; the verb both records **Solution:** PMs call `i_will_plan(task_id, plan)`; the verb both records the plan and transitions the task into `in_progress`.
the plan and transitions the task into `in_progress`.
## Parent Branch Required ## Parent Branch Required
**Symptom:** Can't claim subtask, error "Parent task must be claimed first" **Symptom:** Can't claim subtask, error "Parent task must be claimed first"
**Cause:** Parent task hasn't been claimed/started yet, so it has no **Cause:** Parent task hasn't been claimed/started yet, so it has no branch for the subtask's branch to fork from.
branch for the subtask's branch to fork from.
**Solution:** **Solution:**
1. Parent task must transition to `in_progress` first (PMs: 1. Parent task must transition to `in_progress` first (PMs: `i_will_plan(parent_id, plan)`; devs: `i_will_work_on(parent_id)`).
`i_will_plan(parent_id, plan)`; devs: `i_will_work_on(parent_id)`).
2. Then the subtask's branch will auto-fork from the parent's on claim. 2. Then the subtask's branch will auto-fork from the parent's on claim.
Branches are auto-created hierarchically. No manual creation needed. Branches are auto-created hierarchically. No manual creation needed.
+4 -8
View File
@@ -57,8 +57,7 @@
Cell members → Cell PM → Main PM → Product Owner → CEO Cell members → Cell PM → Main PM → Product Owner → CEO
``` ```
Cannot skip levels or choose target. (Only Main PM / Board call Cannot skip levels or choose target. (Only Main PM / Board call `escalate_to_ceo`; cell members and Cell PMs use `escalate_up`.)
`escalate_to_ceo`; cell members and Cell PMs use `escalate_up`.)
## Tests Failing Before Submit ## Tests Failing Before Submit
@@ -127,10 +126,8 @@ roboco_docs_write({
**Problem**: Sent a `dm` but no response **Problem**: Sent a `dm` but no response
**Check**: **Check**:
1. Is the recipient in your **own cell**? Cross-cell `dm` is denied by 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)`.
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.
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. 3. Did you include `task_id`? It anchors the message to the work.
**Solutions**: **Solutions**:
@@ -144,5 +141,4 @@ roboco_docs_write({
**Cause**: Direct A2A is same-cell only — there is no cross-cell `dm` **Cause**: Direct A2A is same-cell only — there is no cross-cell `dm`
**Solution**: Escalate up the chain. Use `escalate_up(task_id, reason)` **Solution**: Escalate up the chain. Use `escalate_up(task_id, reason)` so your Cell PM can coordinate with the other cell's PM.
so your Cell PM can coordinate with the other cell's PM.
+26 -56
View File
@@ -2,120 +2,90 @@
## Missing Git Token ## Missing Git Token
**Error:** `Project requires a git token for HTTPS repositories` **Error:** `Project requires a git token for HTTPS repositories` (also surfaces as `WorkspaceError` during clone)
(also surfaces as `WorkspaceError` during clone)
**Cause:** No encrypted GitHub PAT on **Cause:** No encrypted GitHub PAT on `projects.git_token_encrypted` for this project.
`projects.git_token_encrypted` for this project.
**Fix:** **Fix:**
1. Open the project's settings tab in the panel 1. Open the project's settings tab in the panel
2. Paste a GitHub Personal Access Token with `repo` scope 2. Paste a GitHub Personal Access Token with `repo` scope
3. Save — the panel encrypts and stores it; the API never returns 3. Save — the panel encrypts and stores it; the API never returns the plaintext
the plaintext
Notes: Notes:
- Each project has its own token (no global fallback) - Each project has its own token (no global fallback)
- Tokens are encrypted at rest with Fernet - Tokens are encrypted at rest with Fernet
- The token is injected only at the MCP layer (commit / clone / PR ops); - The token is injected only at the MCP layer (commit / clone / PR ops); `.git/config` is scrubbed post-clone so a leaked PAT from there is not a recovery path
`.git/config` is scrubbed post-clone so a leaked PAT from there is
not a recovery path
## Workspace Not Found ## Workspace Not Found
**Error:** `Workspace does not exist` **Error:** `Workspace does not exist`
**Cause:** Workspace not cloned yet (or `ROBOCO_WORKSPACE_AUTO_CLONE` **Cause:** Workspace not cloned yet (or `ROBOCO_WORKSPACE_AUTO_CLONE` is `false` and no manual clone has run).
is `false` and no manual clone has run).
**Fix:** **Fix:**
- If `ROBOCO_WORKSPACE_AUTO_CLONE=true` (default), the first MCP verb - If `ROBOCO_WORKSPACE_AUTO_CLONE=true` (default), the first MCP verb that touches the workspace will trigger the clone. Just call your next verb (`i_will_work_on`, `commit`, etc.).
that touches the workspace will trigger the clone. Just call your - Otherwise check `ROBOCO_WORKSPACE_CLONE_TIMEOUT` and the orchestrator logs for a stuck clone.
next verb (`i_will_work_on`, `commit`, etc.).
- Otherwise check `ROBOCO_WORKSPACE_CLONE_TIMEOUT` and the
orchestrator logs for a stuck clone.
## BRANCH_MISMATCH ## BRANCH_MISMATCH
**Error envelope:** **Error envelope:** `Workspace is on '<other-branch>' but task requires '<task-branch>'`
`Workspace is on '<other-branch>' but task requires '<task-branch>'`
**Cause:** You're trying to act on task A while your workspace is still **Cause:** You're trying to act on task A while your workspace is still on task B's branch.
on task B's branch.
**Fix:** Don't checkout by hand — there is no `roboco_git_checkout` **Fix:** Don't checkout by hand — there is no `roboco_git_checkout` tool. Call the verb on the *intended* task instead:
tool. Call the verb on the *intended* task instead:
- Devs: `i_will_work_on(task_id)` switches to that task's branch - Devs: `i_will_work_on(task_id)` switches to that task's branch
- PMs: `i_will_plan(task_id, plan)` switches to that parent task's - PMs: `i_will_plan(task_id, plan)` switches to that parent task's branch
branch
- QA: `claim_review(task_id)` switches to the dev's branch under review - QA: `claim_review(task_id)` switches to the dev's branch under review
If your workspace is dirty, the verb returns an envelope telling you to If your workspace is dirty, the verb returns an envelope telling you to either `commit(...)` first or escalate via `i_am_blocked`.
either `commit(...)` first or escalate via `i_am_blocked`.
## NO_COMMITS on open_pr ## NO_COMMITS on open_pr
**Cause:** No commits on the task yet — the choreographer has nothing **Cause:** No commits on the task yet — the choreographer has nothing to open a PR over.
to open a PR over.
**Fix:** `commit(message=..., files=...)` at least once, then call **Fix:** `commit(message=..., files=...)` at least once, then call `open_pr(task_id)` again.
`open_pr(task_id)` again.
## NO_PR on pass / fail ## NO_PR on pass / fail
**Cause:** The PR was never created — usually because **Cause:** The PR was never created — usually because `open_pr(task_id)` did not run cleanly.
`open_pr(task_id)` did not run cleanly.
**Fix:** Roll back to the dev: have them re-call `open_pr(task_id)` **Fix:** Roll back to the dev: have them re-call `open_pr(task_id)` after fixing whatever blocked the PR opening (see PR Creation Failed, below). QA cannot create the PR.
after fixing whatever blocked the PR opening (see PR Creation Failed,
below). QA cannot create the PR.
## PR Creation Failed (during open_pr) ## PR Creation Failed (during open_pr)
**Causes:** **Causes:**
1. Nothing to push — no commits on the branch 1. Nothing to push — no commits on the branch
2. Branch is on the workspace but not pushed yet (rare; the choreographer 2. Branch is on the workspace but not pushed yet (rare; the choreographer pushes during `commit`, but a stale workspace can drift)
pushes during `commit`, but a stale workspace can drift)
3. Project has no git token configured 3. Project has no git token configured
4. The GitHub repo doesn't allow PRs from your branch (rare; usually 4. The GitHub repo doesn't allow PRs from your branch (rare; usually org-level branch protection)
org-level branch protection)
**Fix:** **Fix:**
- Verify commits exist with `roboco_git_log(project_slug=...)` - Verify commits exist with `roboco_git_log(project_slug=...)`
- Verify the project has a git token (Missing Git Token, above) - Verify the project has a git token (Missing Git Token, above)
- If the task is in a stuck state, `unclaim(task_id)` and re-`claim` - If the task is in a stuck state, `unclaim(task_id)` and re-`claim` to rebuild the branch
to rebuild the branch
## FORCE_PUSH_FORBIDDEN ## FORCE_PUSH_FORBIDDEN
**Cause:** Force-push is CEO-only. Anyone else attempting it (typically **Cause:** Force-push is CEO-only. Anyone else attempting it (typically because their branch diverged) is denied.
because their branch diverged) is denied.
**Fix:** `unclaim(task_id)` and re-`claim` it. The choreographer **Fix:** `unclaim(task_id)` and re-`claim` it. The choreographer rebuilds the branch from the parent's HEAD; replay your commits with `commit(...)`.
rebuilds the branch from the parent's HEAD; replay your commits with
`commit(...)`.
## Merge Conflicts on `complete` ## Merge Conflicts on `complete`
**Cause:** The leaf PR conflicts with the parent branch (cell branch **Cause:** The leaf PR conflicts with the parent branch (cell branch or master).
or master).
**Fix:** This currently surfaces as an error envelope from `complete`. **Fix:** This currently surfaces as an error envelope from `complete`. The recovery path:
The recovery path:
1. PM `unblock(task_id, restore=False)` — frees the task back to the 1. PM `unblock(task_id, restore=False)` — frees the task back to the dev
dev 2. Dev re-claims, the choreographer rebuilds the branch off the latest parent, and they replay their commits
2. Dev re-claims, the choreographer rebuilds the branch off the latest
parent, and they replay their commits
3. Dev `open_pr` again 3. Dev `open_pr` again
4. QA re-runs `pass` (or `fail` if the rebase changed behaviour) 4. QA re-runs `pass` (or `fail` if the rebase changed behaviour)
5. PM `complete` again 5. PM `complete` again
We don't expose a "resolve conflicts in place" path at the agent layer We don't expose a "resolve conflicts in place" path at the agent layer — rebuilds via the lifecycle are the recovery.
— rebuilds via the lifecycle are the recovery.
+5 -12
View File
@@ -31,9 +31,7 @@
2. Task in wrong status 2. Task in wrong status
**Solutions**: **Solutions**:
- Claim + start in one step: `i_will_work_on(task_id, plan="...")` - 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)
(devs), `claim_review(task_id)` (QA), `claim_doc_task(task_id)` (doc),
or `i_will_plan(task_id, plan, approach)` (PMs)
- Check current status - Check current status
Note: Git branches are auto-created on claim, no waiting needed. Note: Git branches are auto-created on claim, no waiting needed.
@@ -67,14 +65,11 @@ Note: Git branches are auto-created on claim, no waiting needed.
**Cause**: Attempting to escalate a task that has a `parent_task_id` **Cause**: Attempting to escalate a task that has a `parent_task_id`
**Solution**: Escalate the parent task instead. Find the parent task ID **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:
(it's on the subtask's `parent_task_id` field, surfaced in your
`give_me_work()` / `triage()` envelope), then escalate the parent:
```python ```python
escalate_to_ceo(task_id=parent_id, reason="...") escalate_to_ceo(task_id=parent_id, reason="...")
``` ```
`escalate_to_ceo` is Main PM / Board only; Cell PMs and cell members `escalate_to_ceo` is Main PM / Board only; Cell PMs and cell members use `escalate_up(task_id, reason)` instead.
use `escalate_up(task_id, reason)` instead.
## Git Task: Parent Branch Required ## Git Task: Parent Branch Required
@@ -93,10 +88,8 @@ use `escalate_up(task_id, reason)` instead.
**Cause**: Trying to complete a parent task while subtasks are still in progress **Cause**: Trying to complete a parent task while subtasks are still in progress
**Solution**: The error message includes which subtask IDs are blocking. Either: **Solution**: The error message includes which subtask IDs are blocking. Either:
1. Complete the blocking subtasks first (drive them through QA → docs → 1. Complete the blocking subtasks first (drive them through QA → docs → `complete(task_id, notes)`)
`complete(task_id, notes)`) 2. Cancel them if no longer needed (PM/CEO only — cancellation is not an agent verb; ask your PM)
2. Cancel them if no longer needed (PM/CEO only — cancellation is not an
agent verb; ask your PM)
## Invalid Task Status for Operation ## Invalid Task Status for Operation
+8 -19
View File
@@ -2,12 +2,9 @@
## Overview ## Overview
Agents collaborate directly through two content tools on the `roboco-do` 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.
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 is about *existing* tasks, NOT task creation. Pass the **Key:** A2A is about *existing* tasks, NOT task creation. Pass the `task_id` you're collaborating on so the message is linked to it.
`task_id` you're collaborating on so the message is linked to it.
## Flow ## Flow
@@ -29,9 +26,7 @@ dm(
) )
``` ```
Cross-cell `dm` is **denied by policy**. If you need something from 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.
another cell, route it through your Cell PM via `escalate_up(task_id,
reason)` — the PM coordinates across cells.
## Channel Posts ## Channel Posts
@@ -44,13 +39,11 @@ say(
) )
``` ```
Call `channels()` first if you're unsure of the exact slug — it returns 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.
the channels you're allowed to post to, so you don't have to guess.
## Task Creation Rules ## Task Creation Rules
**Only PMs create tasks** (via the `delegate` verb). Regular agents **Only PMs create tasks** (via the `delegate` verb). Regular agents cannot create work from a `dm` or `say`.
cannot create work from a `dm` or `say`.
If a conversation surfaces work that needs a new task: 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")` 1. Escalate to your Cell PM: `escalate_up(task_id, reason="Needs a subtask for X")`
@@ -58,12 +51,8 @@ If a conversation surfaces work that needs a new task:
## Permissions ## Permissions
Most roles can `dm` (same-cell) and `say` to their channels, plus read Most roles can `dm` (same-cell) and `say` to their channels, plus read their inbox with `notify_list` / `notify_get`.
their inbox with `notify_list` / `notify_get`.
The **Auditor** is a silent observer: it can read (`notify_list`, 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.
`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 Only PMs and the Board can send ack-required `notify` signals; regular agents use `say` and `dm` only.
agents use `say` and `dm` only.
+5 -14
View File
@@ -14,14 +14,9 @@ Developer/QA/Documenter
CEO CEO
``` ```
`escalate_up` walks this chain **one rung at a time** — it auto-routes to `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.
your immediate escalation target; you cannot choose a higher level or skip
a rung.
The one exception is `escalate_to_ceo`: it is a **separate** verb, 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.
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) ## How to Escalate (up one rung)
@@ -51,9 +46,7 @@ Auto-routes to your escalation target (you cannot choose it).
| **Escalate** | Need a decision / help from above | `escalate_up` | | **Escalate** | Need a decision / help from above | `escalate_up` |
| **Block** | Can't proceed on an external dependency | `i_am_blocked` | | **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 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.
claimed but haven't progressed, use `unclaim(task_id)` to return it to
the pool.
## Blocking a Task ## Blocking a Task
@@ -85,8 +78,7 @@ Requirements:
- Only Main PM, Product Owner, or Head of Marketing can call it - Only Main PM, Product Owner, or Head of Marketing can call it
- **PARENT TASKS ONLY** — subtasks cannot be escalated to CEO - **PARENT TASKS ONLY** — subtasks cannot be escalated to CEO
If you need to escalate a subtask, escalate the parent task instead. The If you need to escalate a subtask, escalate the parent task instead. The CEO reviews the complete feature, not individual components.
CEO reviews the complete feature, not individual components.
## Good Escalation Format ## Good Escalation Format
@@ -105,5 +97,4 @@ Include:
4. Communicate the decision (`say` / `dm` / `notify`) 4. Communicate the decision (`say` / `dm` / `notify`)
5. Unblock if needed: `unblock(task_id)` 5. Unblock if needed: `unblock(task_id)`
CRITICAL: Verbal resolution is NOT enough. To clear a block you MUST call CRITICAL: Verbal resolution is NOT enough. To clear a block you MUST call `unblock(task_id)`.
`unblock(task_id)`.
+4 -10
View File
@@ -19,18 +19,13 @@ Links:
- Journal: {api}/journals/{agent-slug} - Journal: {api}/journals/{agent-slug}
``` ```
**Required:** the conventional `type` (feat, fix, chore, docs, refactor, **Required:** the conventional `type` (feat, fix, chore, docs, refactor, test, style, perf, ci, build) at the start of the subject. The `commit_validator` rejects messages that don't start with one of these followed by `(scope)?:`.
test, style, perf, ci, build) at the start of the subject. The
`commit_validator` rejects messages that don't start with one of these
followed by `(scope)?:`.
**Optional:** `scope` (api, auth, db, ui), `body`, the `files` argument **Optional:** `scope` (api, auth, db, ui), `body`, the `files` argument to scope the commit.
to scope the commit.
## How to commit ## How to commit
Use the **`commit`** verb on the roboco-do MCP — devs and documenters Use the **`commit`** verb on the roboco-do MCP — devs and documenters only. There is no `roboco_git_commit` tool.
only. There is no `roboco_git_commit` tool.
```python ```python
commit( commit(
@@ -50,5 +45,4 @@ The choreographer:
6. Pushes to the agent's branch on origin 6. Pushes to the agent's branch on origin
7. Records the commit on the task (`commits[]` field on `TaskTable`) 7. Records the commit on the task (`commits[]` field on `TaskTable`)
You don't need a separate `push` step. There is no `roboco_git_push` You don't need a separate `push` step. There is no `roboco_git_push` tool.
tool.
+6 -14
View File
@@ -10,17 +10,13 @@ All commits are automatically prefixed with the task ID by the choreographer:
Example: `[a1b2c3d4] Add rate limiting endpoint` Example: `[a1b2c3d4] Add rate limiting endpoint`
You write the message — the prefix is added for you. Don't include You write the message — the prefix is added for you. Don't include `[task-id]` yourself; it gets stripped and re-applied.
`[task-id]` yourself; it gets stripped and re-applied.
## Who Can Commit ## Who Can Commit
`commit` is in the **roboco-do** MCP and is mounted only for **developers** `commit` is in the **roboco-do** MCP and is mounted only for **developers** and **documenters**. PMs delegate code work and call `complete` to merge.
and **documenters**. PMs delegate code work and call `complete` to merge.
There is **no** `roboco_git_commit / _push / _create_pr` MCP tool. The There is **no** `roboco_git_commit / _push / _create_pr` MCP tool. The single `commit` verb covers commit + push + PR-trigger via the choreographer.
single `commit` verb covers commit + push + PR-trigger via the
choreographer.
## Creating Commits ## Creating Commits
@@ -38,8 +34,7 @@ This automatically:
3. Stages the listed files (or everything tracked + modified if omitted) 3. Stages the listed files (or everything tracked + modified if omitted)
4. Pushes to the agent's auto-created branch 4. Pushes to the agent's auto-created branch
5. Records the commit on the task (`commits[]` field on `TaskTable`) 5. Records the commit on the task (`commits[]` field on `TaskTable`)
6. Opens a PR through the choreographer when the task transitions out of 6. Opens a PR through the choreographer when the task transitions out of `in_progress` (no separate `create_pr` call required)
`in_progress` (no separate `create_pr` call required)
## Before Committing ## Before Committing
@@ -50,13 +45,10 @@ This automatically:
## After Committing ## After Committing
You don't push or create a PR yourself. The choreographer pushed the You don't push or create a PR yourself. The choreographer pushed the commit during `commit()`, and the PR is opened/merged as part of the lifecycle transitions:
commit during `commit()`, and the PR is opened/merged as part of the
lifecycle transitions:
- `open_pr(task_id)` — opens the PR (devs) - `open_pr(task_id)` — opens the PR (devs)
- `pass(task_id)` (QA) → `i_documented(task_id)` (doc) → `complete(task_id)` - `pass(task_id)` (QA) → `i_documented(task_id)` (doc) → `complete(task_id)` (cell PM merges the leaf PR; main PM opens the master PR)
(cell PM merges the leaf PR; main PM opens the master PR)
## Viewing Commits and History ## Viewing Commits and History
+6 -17
View File
@@ -7,29 +7,18 @@
## How PRs Are Created ## How PRs Are Created
There is **no** `roboco_git_create_pr` MCP tool. PRs are side-effects of There is **no** `roboco_git_create_pr` MCP tool. PRs are side-effects of lifecycle transitions, driven by the choreographer:
lifecycle transitions, driven by the choreographer:
- **Leaf PR (cell-scoped, `is_root_pr=False`)**: - **Leaf PR (cell-scoped, `is_root_pr=False`)**: Opened automatically when the assigned developer calls `open_pr(task_id)` after their `commit(...)` calls. Merged when the Cell PM calls `complete(task_id, notes)` after QA + docs sign off.
Opened automatically when the assigned developer calls
`open_pr(task_id)` after their `commit(...)` calls. Merged when
the Cell PM calls `complete(task_id, notes)` after QA + docs sign off.
- **Master PR (`is_root_pr=True`)**: - **Master PR (`is_root_pr=True`)**: Opened by the choreographer when the **Main PM** calls `complete(task_id, notes)` on the root parent task. Merged by the CEO via the dashboard once all cell-scoped PRs have been merged into it.
Opened by the choreographer when the **Main PM** calls
`complete(task_id, notes)` on the root parent task. Merged by the CEO
via the dashboard once all cell-scoped PRs have been merged into it.
Title and body are generated from the task templates in Title and body are generated from the task templates in `roboco/templates/git/pr_*.py`. Don't hand-write PR descriptions in the agent prompts — they'll be overridden.
`roboco/templates/git/pr_*.py`. Don't hand-write PR descriptions in the
agent prompts — they'll be overridden.
## Auto-Checkout ## Auto-Checkout
Branches and checkout are handled automatically: Branches and checkout are handled automatically:
- `i_will_work_on(task_id)` (devs) creates the task's branch and checks it - `i_will_work_on(task_id)` (devs) creates the task's branch and checks it out in the agent's workspace.
out in the agent's workspace.
- `i_will_plan(task_id, plan)` (PMs) does the same for parent tasks. - `i_will_plan(task_id, plan)` (PMs) does the same for parent tasks.
- Workspace dirty? The verb returns an error envelope; clean up first - Workspace dirty? The verb returns an error envelope; clean up first with `commit(...)` or escalate via `i_am_blocked(task_id, reason)`.
with `commit(...)` or escalate via `i_am_blocked(task_id, reason)`.
+3 -8
View File
@@ -9,9 +9,7 @@
## The Tool ## The Tool
Journaling is a single content tool: `note(text, scope, ...)` on the 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.
`roboco-do` MCP server. There is **no** separate `roboco_journal_*` tool —
the `scope` argument selects the kind of entry.
| `scope` | Use For | | `scope` | Use For |
|---------|---------| |---------|---------|
@@ -55,9 +53,7 @@ note(
) )
``` ```
`options`, `consequences`, and `next_steps` accept either a list or a `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.
single value. For `decision` and `reflect` scopes the structured fields
are recommended; the note is always recorded even if some are omitted.
## Required Reflections ## Required Reflections
@@ -77,8 +73,7 @@ note(
## Searching Journals ## Searching Journals
Journal entries are indexed into the knowledge base. Search them through Journal entries are indexed into the knowledge base. Search them through the `roboco-optimal` RAG tools (there is no dedicated journal-search verb):
the `roboco-optimal` RAG tools (there is no dedicated journal-search verb):
```python ```python
# Semantic search across the KB, filtered to journal entries # Semantic search across the KB, filtered to journal entries
+14 -34
View File
@@ -2,15 +2,11 @@
## When PRs Are Created ## When PRs Are Created
PRs are opened **before** QA review, not during `awaiting_documentation`. PRs are opened **before** QA review, not during `awaiting_documentation`. The choreographer creates the PR as a side-effect of the developer's `open_pr(task_id)` transition (`verifying → awaiting_qa`).
The choreographer creates the PR as a side-effect of the developer's
`open_pr(task_id)` transition (`verifying → awaiting_qa`).
This is by design: QA reviews the real PR diff on GitHub, and the This is by design: QA reviews the real PR diff on GitHub, and the downstream PM/CEO approval chain operates on a PR that already exists.
downstream PM/CEO approval chain operates on a PR that already exists.
You do **not** call any tool to create a PR. There is no You do **not** call any tool to create a PR. There is no `roboco_git_create_pr` MCP tool.
`roboco_git_create_pr` MCP tool.
## How the dev triggers it ## How the dev triggers it
@@ -27,28 +23,22 @@ open_pr(task_id="<task>")
The transition enforces (`enforcement/task_lifecycle.py`): The transition enforces (`enforcement/task_lifecycle.py`):
- `self_verified=True` — set when you call `i_am_done()` or - `self_verified=True` — set when you call `i_am_done()` or `verify(task_id)` first
`verify(task_id)` first
- `commits` non-empty — at least one commit on the task - `commits` non-empty — at least one commit on the task
- `progress_updates` non-empty — at least one note on what changed - `progress_updates` non-empty — at least one note on what changed
- `pr_number` is set automatically by the choreographer; you don't pass it - `pr_number` is set automatically by the choreographer; you don't pass it
If any precondition is missing, the verb returns an envelope explaining If any precondition is missing, the verb returns an envelope explaining what's missing and how to remediate.
what's missing and how to remediate.
## PR Title and Body ## PR Title and Body
Generated from templates in `roboco/templates/git/pr_internal.py` and Generated from templates in `roboco/templates/git/pr_internal.py` and `roboco/templates/git/pr_root.py`. You don't write the body by hand — it's filled with task title, acceptance criteria, the dev's notes, and the standard traceability links.
`roboco/templates/git/pr_root.py`. You don't write the body by hand —
it's filled with task title, acceptance criteria, the dev's notes, and
the standard traceability links.
Title format: `[TASK-{root-id:8}:{task-id:8}] {task-title}`. Title format: `[TASK-{root-id:8}:{task-id:8}] {task-title}`.
## Parallel Documenter Phase ## Parallel Documenter Phase
After QA passes, the task transitions to `awaiting_documentation` and After QA passes, the task transitions to `awaiting_documentation` and runs documenter + dev in parallel:
runs documenter + dev in parallel:
| Agent | Action | Flag set | | Agent | Action | Flag set |
|-------|--------|----------| |-------|--------|----------|
@@ -59,35 +49,25 @@ Task transitions to `awaiting_pm_review` when both are true.
## PM Merges via `complete` ## PM Merges via `complete`
After `awaiting_pm_review`, the Cell PM calls `complete(task_id, notes)`. After `awaiting_pm_review`, the Cell PM calls `complete(task_id, notes)`. The choreographer:
The choreographer:
1. Verifies all subtasks are in a terminal state 1. Verifies all subtasks are in a terminal state
2. Verifies the PR is reviewable 2. Verifies the PR is reviewable
3. Merges the leaf PR into the parent branch (squash by default) 3. Merges the leaf PR into the parent branch (squash by default)
4. Transitions the task to `completed` 4. Transitions the task to `completed`
For the root parent, **Main PM**'s `complete` opens the master PR and For the root parent, **Main PM**'s `complete` opens the master PR and escalates to CEO via `escalate_to_ceo` semantics.
escalates to CEO via `escalate_to_ceo` semantics.
There is no `roboco_git_merge_pr` MCP tool. There is no `roboco_git_merge_pr` MCP tool.
## Prerequisites ## Prerequisites
- **Git token:** the project must have an encrypted GitHub PAT set on - **Git token:** the project must have an encrypted GitHub PAT set on `projects.git_token_encrypted`. Without it, the workspace clone — and therefore everything downstream — fails with `WorkspaceError`.
`projects.git_token_encrypted`. Without it, the workspace clone — and
therefore everything downstream — fails with `WorkspaceError`.
- **Token scope:** `repo` (for branch push, PR create, PR merge). - **Token scope:** `repo` (for branch push, PR create, PR merge).
- **Default branch:** `projects.default_branch` is the merge target for - **Default branch:** `projects.default_branch` is the merge target for the master PR (typically `master`).
the master PR (typically `master`).
## Troubleshooting ## Troubleshooting
- `NO_COMMITS` on `open_pr` → call `commit(...)` first; nothing to - `NO_COMMITS` on `open_pr` → call `commit(...)` first; nothing to open a PR over.
open a PR over. - `NO_PR` on `pass`/`fail` → the choreographer didn't open a PR; check the workspace state with `roboco_git_status` and re-call `open_pr` once the workspace is clean.
- `NO_PR` on `pass`/`fail` the choreographer didn't open a PR; check - `FORCE_PUSH_FORBIDDEN` → only the CEO may force-push. If your branch diverged, `unclaim` and re-`claim` the task; the choreographer rebuilds the branch.
the workspace state with `roboco_git_status` and re-call
`open_pr` once the workspace is clean.
- `FORCE_PUSH_FORBIDDEN` → only the CEO may force-push. If your branch
diverged, `unclaim` and re-`claim` the task; the choreographer
rebuilds the branch.
+5 -13
View File
@@ -3,8 +3,7 @@
## Preconditions ## Preconditions
- Task is in `awaiting_qa` status - Task is in `awaiting_qa` status
- The developer's PR is open (the choreographer opened it during their - The developer's PR is open (the choreographer opened it during their `open_pr(task_id)` call)
`open_pr(task_id)` call)
- You are not the original developer of the task (self-review guard) - You are not the original developer of the task (self-review guard)
## Steps ## Steps
@@ -39,9 +38,7 @@ note(text="Verified AC #1 (429 on 101st req), #2 (TTL match), #3 "
task_id="<task>") task_id="<task>")
``` ```
There is no `roboco_task_claim / _start / _qa_pass / _qa_fail` and no There is no `roboco_task_claim / _start / _qa_pass / _qa_fail` and no `roboco_git_checkout`. The verbs above (`claim_review`, `pass`, `fail`) are the actual surface; branch checkout is a side-effect of `claim_review`.
`roboco_git_checkout`. The verbs above (`claim_review`, `pass`, `fail`)
are the actual surface; branch checkout is a side-effect of `claim_review`.
## Review Checklist ## Review Checklist
@@ -72,8 +69,7 @@ Result:
- Task advances to `awaiting_documentation` - Task advances to `awaiting_documentation`
- Documenter and the original dev work in parallel from here - Documenter and the original dev work in parallel from here
- The PR stays open; it will be merged later by the Cell PM via - The PR stays open; it will be merged later by the Cell PM via `complete(task_id, ...)`
`complete(task_id, ...)`
## Failing QA ## Failing QA
@@ -111,14 +107,10 @@ note(
## Self-Review Prevention ## Self-Review Prevention
The system blocks QA from reviewing their own dev work. The original The system blocks QA from reviewing their own dev work. The original developer is recorded in `quick_context` at submit-for-qa time. If `qa_agent_id == original_developer_id`, **all** QA actions on the task return `not_authorized`:
developer is recorded in `quick_context` at submit-for-qa time. If
`qa_agent_id == original_developer_id`, **all** QA actions on the task
return `not_authorized`:
- `claim_review` — FORBIDDEN - `claim_review` — FORBIDDEN
- `pass` — FORBIDDEN (defence-in-depth even if claim somehow succeeded) - `pass` — FORBIDDEN (defence-in-depth even if claim somehow succeeded)
- `fail` — FORBIDDEN (same) - `fail` — FORBIDDEN (same)
Enforced at the gateway layer in Enforced at the gateway layer in `roboco/services/gateway/choreographer/_impl.py`.
`roboco/services/gateway/choreographer/_impl.py`.
+2 -6
View File
@@ -25,9 +25,7 @@ claim_doc_task(task_id) # Documenter
# - assigned_to: your agent ID # - assigned_to: your agent ID
``` ```
The claim verb both claims and starts the task — there is no separate 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.
`start` call. For developers, `i_will_work_on` also creates and checks
out the `feature/{team}/{task-hierarchy}` branch.
## Before Claiming ## Before Claiming
@@ -62,9 +60,7 @@ unclaim(task_id)
# - You can now claim new work # - You can now claim new work
``` ```
`unclaim` takes only the `task_id` — it returns the task to the pool for `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.
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:** **When to use unclaim:**
- Task is out of your team's scope - Task is out of your team's scope
+17 -46
View File
@@ -2,17 +2,13 @@
## Overview ## Overview
Planning is a **PM activity**. When a PM (Cell PM or Main PM) picks up a 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`.
coordination or parent task, they record a plan with `i_will_plan` and
then fan the work out into subtasks with `delegate`.
``` ```
triage / give_me_work → i_will_plan → delegate (one per subtask) → i_am_idle 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 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.
`plan` argument directly to `i_will_work_on(task_id, plan="...")` when
they claim a coding task.
## Submitting a Plan (PM) ## Submitting a Plan (PM)
@@ -32,8 +28,7 @@ i_will_plan(
) )
``` ```
After `i_will_plan`, the envelope's `next` field points you at After `i_will_plan`, the envelope's `next` field points you at `delegate` — create one subtask per unit of work:
`delegate` — create one subtask per unit of work:
```python ```python
delegate( delegate(
@@ -52,61 +47,37 @@ delegate(
## Acceptance-Criteria Coverage ## Acceptance-Criteria Coverage
When you decompose a parent task, declare which parent criteria each subtask is When you decompose a parent task, declare which parent criteria each subtask is responsible for with **`covers_parent_criteria`** (a list of the parent's `acceptance_criteria_ids`). This is what lets the org prove a decomposition covers the parent's full intent — and it drives two gates and your coverage briefing.
responsible for with **`covers_parent_criteria`** (a list of the parent's
`acceptance_criteria_ids`). This is what lets the org prove a decomposition
covers the parent's full intent — and it drives two gates and your coverage
briefing.
After `i_will_plan` and after each `delegate`, your envelope carries a coverage After `i_will_plan` and after each `delegate`, your envelope carries a coverage view of the parent so you can see what is still unmapped:
view of the parent so you can see what is still unmapped:
- **`parent_ac_coverage`** — one entry per parent criterion: its `id`, `text`, - **`parent_ac_coverage`** — one entry per parent criterion: its `id`, `text`, whether a live subtask `claimed` it, and whether a completed subtask `verified` it.
whether a live subtask `claimed` it, and whether a completed subtask - **`unclaimed_parent_acs`** — the parent criterion ids that no live subtask covers yet. Keep delegating until this is empty.
`verified` it.
- **`unclaimed_parent_acs`** — the parent criterion ids that no live subtask
covers yet. Keep delegating until this is empty.
Two gates build on the coverage link: Two gates build on the coverage link:
- **Decomposition floor** — you cannot go `i_am_idle` on a parent while a - **Decomposition floor** — you cannot go `i_am_idle` on a parent while a criterion is still unclaimed. Delegate (or `reassign`) subtasks until every criterion is covered.
criterion is still unclaimed. Delegate (or `reassign`) subtasks until every - **Roll-up gate** — a parent cannot `complete`, `submit_up`, or `escalate_to_ceo` unless every criterion traces to a child that **passed QA** on it.
criterion is covered.
- **Roll-up gate** — a parent cannot `complete`, `submit_up`, or
`escalate_to_ceo` unless every criterion traces to a child that **passed QA**
on it.
Both gates are **safe-by-construction**: they stay inert until you start Both gates are **safe-by-construction**: they stay inert until you start declaring `covers_parent_criteria`, so a decomposition that never declares coverage is never blocked. Declaring coverage is how you opt your parent into the guarantee.
declaring `covers_parent_criteria`, so a decomposition that never declares
coverage is never blocked. Declaring coverage is how you opt your parent into
the guarantee.
## Delegating Code Work: Per-Dev Queues ## Delegating Code Work: Per-Dev Queues
For code subtasks, delegate each developer their **full queue up front** rather For code subtasks, delegate each developer their **full queue up front** rather than one task at a time. Both of a cell's developers build in parallel, and each works its own queue one task at a time, in order:
than one task at a time. Both of a cell's developers build in parallel, and each
works its own queue one task at a time, in order:
- A per-lane dispatch barrier holds a developer's later subtasks until their - A per-lane dispatch barrier holds a developer's later subtasks until their current one is in flight — so each dev's lane stays sequenced while the two devs run concurrently.
current one is in flight — so each dev's lane stays sequenced while the two - Leaf PRs are still merged into the shared cell branch **in sequence**, not in parallel.
devs run concurrently.
- Leaf PRs are still merged into the shared cell branch **in sequence**, not
in parallel.
- Order the queue by dependency: the subtask others build on goes first. - Order the queue by dependency: the subtask others build on goes first.
Caps still apply: at most 12 subtasks per parent, and same-title duplicate Caps still apply: at most 12 subtasks per parent, and same-title duplicate subtasks are rejected.
subtasks are rejected.
## Git Workflow ## Git Workflow
All code tasks follow the git workflow: All code tasks follow the git workflow:
- **Branches are auto-created when a developer claims the task** via - **Branches are auto-created when a developer claims the task** via `i_will_work_on` — no manual branch creation
`i_will_work_on` — no manual branch creation
- Root tasks: branch created from the default branch (main/master) - Root tasks: branch created from the default branch (main/master)
- Subtasks: branch forked from the parent's branch - Subtasks: branch forked from the parent's branch
Coordination/parent tasks that only plan and delegate (no code) do not Coordination/parent tasks that only plan and delegate (no code) do not need a branch of their own.
need a branch of their own.
Hierarchical branch naming uses `--` between task IDs to avoid git ref Hierarchical branch naming uses `--` between task IDs to avoid git ref conflicts: `feature/{team}/{ROOT}--{SUB}--{SUBSUB}`.
conflicts: `feature/{team}/{ROOT}--{SUB}--{SUBSUB}`.
+1 -5
View File
@@ -73,8 +73,4 @@ backlog → pending (a PM activates the task during `triage`)
## Checking State ## Checking State
You don't poll task state directly — every flow verb returns a 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)`.
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)`.
+1 -2
View File
@@ -14,5 +14,4 @@ Documentation for the UX/UI Cell team.
## Contributing ## Contributing
UX/UI team members should request documentation updates through the Cell PM. UX/UI team members should request documentation updates through the Cell PM. Only the UX/UI Documenter (ux-doc) can write to this directory.
Only the UX/UI Documenter (ux-doc) can write to this directory.
+5 -17
View File
@@ -1,9 +1,6 @@
# RoboCo Control Panel # RoboCo Control Panel
Next.js 16 control panel for the RoboCo AI agent system. Formerly a Next.js 16 control panel for the RoboCo AI agent system. Formerly a separate repository (`rennf93/roboco-panel`), now vendored under `panel/` in this monorepo so `docker compose up -d` brings up the whole stack from one place.
separate repository (`rennf93/roboco-panel`), now vendored under
`panel/` in this monorepo so `docker compose up -d` brings up the
whole stack from one place.
## Stack ## Stack
@@ -23,16 +20,12 @@ Use the root-level Docker Compose:
docker compose up -d docker compose up -d
``` ```
The panel is built as part of the compose stack via The panel is built as part of the compose stack via `docker/panel.Dockerfile` and served internally on port 3000. Nginx (also in the compose stack) is the single externally-exposed service on `http://localhost:3000` and routes:
`docker/panel.Dockerfile` and served internally on port 3000.
Nginx (also in the compose stack) is the single externally-exposed
service on `http://localhost:3000` and routes:
- `/api/*` and `/ws/*` → orchestrator (FastAPI, port 8000) - `/api/*` and `/ws/*` → orchestrator (FastAPI, port 8000)
- everything else → the Next.js panel - everything else → the Next.js panel
The panel uses relative URLs (`/api/v1`, `/ws`) so nothing here The panel uses relative URLs (`/api/v1`, `/ws`) so nothing here needs a backend URL in `.env`.
needs a backend URL in `.env`.
## Running the panel alone for UI development ## Running the panel alone for UI development
@@ -42,10 +35,7 @@ pnpm install
pnpm dev pnpm dev
``` ```
That gives you Next dev-server on `localhost:3000`, but you still need That gives you Next dev-server on `localhost:3000`, but you still need the orchestrator reachable at `localhost:8000` (or via nginx) for API calls to work. Easiest: `docker compose up -d` the backend services, then run `pnpm dev` against that.
the orchestrator reachable at `localhost:8000` (or via nginx) for API
calls to work. Easiest: `docker compose up -d` the backend services,
then run `pnpm dev` against that.
## Build scripts ## Build scripts
@@ -64,6 +54,4 @@ then run `pnpm dev` against that.
## Backend schema changes ## Backend schema changes
When the backend changes response shapes, mirror them in `src/types/` When the backend changes response shapes, mirror them in `src/types/` and the relevant `src/lib/api/` module. Keep API paths relative so nginx routing keeps working.
and the relevant `src/lib/api/` module. Keep API paths relative so
nginx routing keeps working.
+8 -28
View File
@@ -96,12 +96,7 @@ docker ps --filter "name=roboco-agent" -q | xargs docker stop
## Creating Tasks ## Creating Tasks
`POST /api/tasks` has no silent defaults — `title`, `description` (min 20 `POST /api/tasks` has no silent defaults — `title`, `description` (min 20 chars), `acceptance_criteria` (at least one), `team`, `task_type`, `nature`, and `estimated_complexity` are all required, plus exactly one of `project_id` (the repo this task targets) or `product_id` (a cell→project map for a fan-out task). See the `TaskCreate` schema in `roboco/models/task.py` (or the Swagger UI at [docs](./docs)) for the full field list and enum values.
chars), `acceptance_criteria` (at least one), `team`, `task_type`, `nature`,
and `estimated_complexity` are all required, plus exactly one of `project_id`
(the repo this task targets) or `product_id` (a cell→project map for a fan-out
task). See the `TaskCreate` schema in `roboco/models/task.py` (or the Swagger
UI at `/docs`) for the full field list and enum values.
```bash ```bash
curl -X POST http://localhost:8000/api/tasks \ curl -X POST http://localhost:8000/api/tasks \
@@ -122,9 +117,7 @@ curl -X POST http://localhost:8000/api/tasks \
}' }'
``` ```
Enum values: `task_type` ∈ {`code`, `documentation`, `research`, `planning`, Enum values: `task_type` ∈ {`code`, `documentation`, `research`, `planning`, `design`, `administrative`}; `nature` ∈ {`technical`, `non_technical`}; `estimated_complexity` ∈ {`low`, `medium`, `high`}.
`design`, `administrative`}; `nature` ∈ {`technical`, `non_technical`};
`estimated_complexity` ∈ {`low`, `medium`, `high`}.
## Task Lifecycle ## Task Lifecycle
@@ -235,14 +228,9 @@ docker logs -f roboco-agent-be-dev-1
### Resource Usage ### Resource Usage
RAM is modest. Agent containers are spawned on demand and torn down when RAM is modest. Agent containers are spawned on demand and torn down when their work is done, so you rarely have more than a handful live at once — and the on-demand Intake and Secretary only run while you're interacting with them. Steady-state memory is dominated by the standing services (Postgres, Redis, and especially Ollama with its models loaded), not by the agents.
their work is done, so you rarely have more than a handful live at once — and
the on-demand Intake and Secretary only run while you're interacting with them.
Steady-state memory is dominated by the standing services (Postgres, Redis,
and especially Ollama with its models loaded), not by the agents.
Measured at idle on the reference NAS (full stack up, no task running), the Measured at idle on the reference NAS (full stack up, no task running), the standing services use roughly:
standing services use roughly:
| Service | RAM (idle) | | Service | RAM (idle) |
|---------|------------| |---------|------------|
@@ -253,19 +241,11 @@ standing services use roughly:
| Redis | ~15 MB | | Redis | ~15 MB |
| nginx | ~10 MB | | nginx | ~10 MB |
So the whole standing stack idles around ~2.5 GB, almost all of it Ollama; So the whole standing stack idles around ~2.5 GB, almost all of it Ollama; the application itself is a few hundred MB.
the application itself is a few hundred MB. (These are idle figures — peak
memory while agents are actively working will be higher, and is best read
live with `docker stats` while a task is in flight.)
Storage is the larger footprint: the image set. The agent images all build Under load it stays light. Measured with five agents working concurrently (two cells' developers plus a cell PM), each agent container used ~0.50.65 GB, and the whole stack — agents plus services — peaked around ~6.6 GB, roughly 5% of a 128 GB box. The orchestrator itself grows with concurrency (~150 MB idle → ~1 GB while managing several live agent sessions and their streams), and a developer briefly spikes to a few CPU cores while it is actively generating. Even at full-fleet peak you stay well under ~10 GB — RAM is not the constraint; storage is.
`FROM` a shared base layer, so on disk they cost far less than their nominal
sizes added together. For reference, the panel image is ~230 MB, the Storage is the larger footprint: the image set. The agent images all build `FROM` a shared base layer, so on disk they cost far less than their nominal sizes added together. For reference, the panel image is ~230 MB, the orchestrator ~0.9 GB, the agent base ~1.1 GB, and each agent image ~1.1 GB (the frontend dev/QA images are larger, ~1.9 GB, for their browser/Node toolchain) — but the shared base means the real on-disk total is well below their sum. `docker system prune` reclaims old image versions, stopped agent containers, and build cache (typically a few GB).
orchestrator ~0.9 GB, the agent base ~1.1 GB, and each agent image ~1.1 GB
(the frontend dev/QA images are larger, ~1.9 GB, for their browser/Node
toolchain) — but the shared base means the real on-disk total is well below
their sum. `docker system prune` reclaims old image versions, stopped agent
containers, and build cache (typically a few GB).
Monitor with: Monitor with:
```bash ```bash