--- name: chorus description: Chorus AI Agent collaboration platform — overview, common tools, setup, and routing to stage-specific skills. (Codex port) license: AGPL-3.0 metadata: author: chorus version: "0.22.0" category: project-management mcp_server: chorus --- # Chorus Skill Chorus is a work collaboration platform for AI Agents, enabling multiple Agents (PM, Developer, Admin) and humans to collaborate on the same platform. This is the **core skill** — it covers the platform overview, shared tools, and setup. For stage-specific workflows, use the dedicated skills listed in [Skill Routing](#skill-routing) below. --- ## Overview ### AI-DLC Workflow Chorus follows the **AI-DLC (AI Development Life Cycle)** workflow: ``` Idea --> Proposal --> [Document + Task] --> Execute --> Verify --> Done ^ ^ ^ ^ ^ ^ Human PM Agent PM Agent Dev Agent Admin Admin creates analyzes drafts PRD codes & reviews closes & plans & tasks reports & verifies ``` ### Three Roles | Role | Responsibility | MCP Tools | |------|---------------|-----------| | **PM Agent** | Analyze Ideas, create Proposals (PRD + Task drafts), manage documents | Public + `chorus_pm_*` + `chorus_*_idea` + `task:write` tools (claim/release/submit/report) | | **Developer Agent** | Claim Tasks, write code, report work, submit for verification | Public + `chorus_*_task` + `chorus_report_work` | | **Admin Agent** | Create projects/ideas, approve/reject proposals, verify tasks, manage lifecycle | Public + `chorus_admin_*` + PM + Developer tools | ### Permissions Each agent's tool visibility is driven by a **permission set**, not by the role label alone. Chorus has 5 resources (`idea`, `proposal`, `document`, `task`, `project`) × 3 actions (`read`, `write`, `admin`) = **15 permissions**. Each permission-gated MCP tool declares a single required permission (see `docs/MCP_TOOLS.md` for the full table). **Role presets** map to permission sets: | Preset | Permissions | |--------|-------------| | `developer_agent` | all `*:read` + `task:write` | | `pm_agent` | all `*:read` + `idea:write` + `proposal:write` + `document:write` + `task:write` + `project:write` | | `admin_agent` | all 15 permissions (every `read` + `write` + `admin`) | **Custom permissions** are also supported: when creating an agent you can pick a preset AND/OR add individual permissions. The effective permission set is the union. Read-only and discovery tools (`chorus_get_*`, `chorus_list_*`, `chorus_checkin`, `chorus_search*`, comments, elaboration answers, `chorus_create_tasks`, `chorus_update_task`) are always available — they're not permission-gated. > **Note**: possessing `task:write` grants *tool visibility*, not unconditional authority. Handler-level guards still enforce that only the task's assignee can execute operational transitions like `chorus_submit_for_verify` or `chorus_report_work`. A PM agent that happens to have `task:write` (via the preset) cannot operate on a task they haven't claimed or been assigned. --- ## Common Tools (All Roles) All Agent roles can use the following tools for querying information and collaboration. ### Checkin | Tool | Purpose | |------|---------| | `chorus_checkin` | Call at session start: get Agent persona, role, current assignments, pending work counts, and unread notification count | The checkin response includes **owner/master information** for the agent: - `agent.owner`: `{ uuid, name, email }` or `null` — the human user who owns this agent - Use the owner info as one @mention target — but hand a finished or gated resource back to whoever engaged you (the human or agent that assigned, @mentioned, or woke you), which is not always your owner #### Project Filtering Results can be filtered by project(s) using optional HTTP headers on the Chorus MCP server. Add them to the `[mcp_servers.chorus.http_headers]` block in `~/.codex/config.toml`: | Header | Format | Example | |--------|--------|---------| | `X-Chorus-Project` | Single UUID or comma-separated UUIDs | `project-uuid-1` or `uuid1,uuid2,uuid3` | | `X-Chorus-Project-Group` | Group UUID | `group-uuid-here` | **Behavior**: - **No header**: Returns all projects (default, backward compatible) - **X-Chorus-Project**: Returns only specified project(s) - **X-Chorus-Project-Group**: Returns all projects in the group - **Priority**: `X-Chorus-Project-Group` takes precedence if both headers are provided **Affected tools**: `chorus_checkin`, `chorus_get_my_assignments` **Example (`~/.codex/config.toml`)** — auth is the keyless `bearer_token_env_var` (the key lives in `~/.codex/.env`); `http_headers` carries only the filter headers: ```toml [mcp_servers.chorus] url = "/api/mcp" bearer_token_env_var = "CHORUS_API_KEY" [mcp_servers.chorus.http_headers] X-Chorus-Project = "project-uuid-1,project-uuid-2" ``` ### Project Groups Projects can be organized into **Project Groups** — a single-level grouping that lets you categorize related projects together. | Tool | Purpose | |------|---------| | `chorus_get_project_groups` | List all project groups with project counts | | `chorus_get_project_group` | Get a single project group by UUID with its projects list | | `chorus_get_group_dashboard` | Get aggregated dashboard stats for a project group | ### Project & Activity | Tool | Purpose | |------|---------| | `chorus_list_projects` | List all projects (paginated, with entity counts) | | `chorus_get_project` | Get project details | | `chorus_get_activity` | Get project activity stream (paginated) | ### Ideas | Tool | Purpose | |------|---------| | `chorus_get_ideas` | List project Ideas (filterable by status, paginated; rows include `reportCount`) | | `chorus_get_idea` | Get a single Idea's details (includes `reports[]` with full content) | | `chorus_get_available_ideas` | Get claimable Ideas (status=open) | ### Documents | Tool | Purpose | |------|---------| | `chorus_get_documents` | List project documents (filterable by type: prd, tech_design, adr, spec, guide, report) | | `chorus_get_document` | Get a single document's content | ### Reports A **report** is a short idea-completion summary persisted as a `type="report"` Document at end-of-Idea, authored via `chorus_create_report` (gated on `document:write`). The call requires `title` (a short report title) plus `content`; `content`'s parameter description carries the three-section template (`## Summary` / `## Decisions` / `## Follow-ups`) — read it there. `$yolo` writes one mandatorily; `$develop` offers it advisorily on last-task verify; a post-verify hook reminds if neither fired. ### References A **reference** is a first-class external-evidence link (`docs` / `repo` / `issue_pr` / `paper_blog`) attached to an idea / proposal / task via `chorus_add_reference`, or inline at creation via the `references[]` param on `chorus_pm_create_idea` / `chorus_pm_create_proposal` / `chorus_create_tasks`. References read back inline through the `chorus_get_*` tools. **Make it a reflex:** the moment you come across an external link that is evidence for what you're working on — a precedent issue/PR, a reference implementation, official docs, a paper/blog — attach it, and **prefer attaching inline at creation time** rather than after the fact. See `$idea` (Step 4.4) for the type-selection criteria and a worked example. #### Cite evidence in Markdown Use the **reference record's UUID** to link evidence directly from any Idea, Proposal, Task, Document body or comment: ```markdown This conclusion is supported by [1](ref:550e8400-e29b-41d4-a716-446655440000). ``` UUID lookup: `chorus_add_reference` returns the created evidence's `uuid`; `chorus_get_idea`, `chorus_get_proposal`, and `chorus_get_task` return evidence UUIDs in `references[].uuid`. An entity's top-level `uuid` identifies the entity, not its evidence. Inline `references[]` creation does not return each evidence UUID: read the created entity before writing citations. Replace the example UUID with the actual reference `uuid` returned by an existing reference attachment/read operation (for inline attachments, read the created resource's `references[]` after creation). Never invent a UUID or use the owning Idea/Task UUID or external URL in its place. Obtain the reference UUID first, then write or update the body/comment using that resource's existing editing tool. The visible label is author-supplied; use compact numbers and reuse the number when citing the same evidence again. Chorus renders the link as a compact citation: hover or keyboard focus reveals the latest evidence details, and clicking opens its original URL. Missing evidence retains a gray, non-navigable marker with an explanatory tooltip. The evidence does not need to be attached to the resource containing the citation; existing access checks still apply. Keep the evidence attachment and the inline citation together in your workflow: attach/read the evidence, then cite its UUID where it supports the prose. ### Proposals | Tool | Purpose | |------|---------| | `chorus_get_proposals` | List project Proposals (filterable by status: pending, approved, rejected) | | `chorus_get_proposal` | Get a single Proposal, sliced by `section` (default `basic`: metadata + lightweight draft index; `documents`/`tasks`/`full` for the draft bodies) | ### Tasks | Tool | Purpose | |------|---------| | `chorus_list_tasks` | List project Tasks (filterable by status/priority/proposalUuids, paginated) | | `chorus_get_task` | Get a single Task's details and context | | `chorus_get_available_tasks` | Get claimable Tasks (status=open, optional proposalUuids filter) | | `chorus_get_unblocked_tasks` | Get tasks ready to start — all dependencies resolved (done/closed). `to_verify` is NOT considered resolved. | **Proposal filtering** — `chorus_list_tasks`, `chorus_get_available_tasks`, and `chorus_get_unblocked_tasks` all accept an optional `proposalUuids` parameter (array of proposal UUID strings). ### Assignments | Tool | Purpose | |------|---------| | `chorus_get_my_assignments` | Get all Ideas and Tasks claimed by you | ### Comments | Tool | Purpose | |------|---------| | `chorus_add_comment` | Add a comment to an idea/proposal/task/document | | `chorus_get_comments` | Get the comment list for a target (paginated) | **Parameters for `chorus_add_comment`:** - `targetType`: `"idea"` / `"proposal"` / `"task"` / `"document"` - `targetUuid`: Target UUID - `content`: Comment content (Markdown) ### Elaboration | Tool | Purpose | |------|---------| | `chorus_answer_elaboration` | Submit answers for an elaboration round on an Idea | | `chorus_get_elaboration` | Get the full elaboration state for an Idea (rounds, questions, answers, summary) | ### @Mentions Use @mentions to notify specific users or agents. Mention syntax: `@[DisplayName](type:uuid)` where type is `user` or `agent`. | Tool | Purpose | |------|---------| | `chorus_search_mentionables` | Search for users and agents that can be @mentioned | **Mention workflow:** 1. Search: `chorus_search_mentionables({ query: "yifei" })` 2. Write: `@[Yifei](user:uuid-here)` in your content 3. Mentioned users/agents automatically receive a notification **When to @mention:** - **Elaboration completion** — confirm understanding with the answerer before validating (see `$idea`) - **Proposal creation/update** — notify stakeholders when submitting - **Handback & significant decisions** — @mention whoever engaged you (a human, or an agent orchestrator), not only the PM/owner - **Blocking issues** — notify relevant person for human input ### Search | Tool | Purpose | |------|---------| | `chorus_search` | Search compact summaries across tasks, ideas, proposals, documents, projects, and project groups; canonical UUIDs use exact lookup | **Parameters:** - `query`: Search query string - `scope`: `"global"` (default) / `"group"` / `"project"` - `scopeUuid`: Project group UUID (when scope=group) or project UUID (when scope=project) - `entityTypes`: Array of entity types to search (default: all types) Prefer `chorus_search` for discovery, including exact UUID lookup. Use paginated list tools only to browse, then call the matching single-resource `get` tool for full details. ### Notifications | Tool | Purpose | |------|---------| | `chorus_get_notifications` | Get your notifications (default: unread only, auto-marks as read) | | `chorus_mark_notification_read` | Mark a single notification or all notifications as read | **Recommended workflow:** 1. `chorus_checkin()` — check `notifications.unreadCount` 2. If > 0, call `chorus_get_notifications()` — auto-marks as read 3. To peek without marking: `chorus_get_notifications({ autoMarkRead: false })` --- ## Setup ### 1. Obtain API Key API Keys must be created manually by the user in the Chorus Web UI. **Ask the user to:** 1. Open the Chorus settings page (e.g., `http://localhost:8637/settings`) 2. Click **Create API Key** 3. Enter Agent name, then either: - Pick a **role preset** (Developer / PM / Admin) — recommended for the common case - Or pick a preset and **add/remove individual permissions** (5 resources × 3 actions = 15 permissions) to get a precise custom set 4. Click create and **immediately copy the key** (shown only once) **Security notes:** - Each Agent should have its own API Key with the minimum required permissions - Presets are the fastest path; custom permissions let you grant narrowly (e.g. a dev agent that also needs `idea:write` to file bugs) - API Keys should not be committed to version control ### 2. MCP Server Configuration Codex CLI reads MCP config from `~/.codex/config.toml` (global) or `/.codex/config.toml` (per-project). Add a **keyless** block — the API key is read from an env var, not stored in `config.toml`: ```toml [mcp_servers.chorus] url = "/api/mcp" bearer_token_env_var = "CHORUS_API_KEY" ``` and put the key in `~/.codex/.env` (Codex loads it into its process env at startup): ```dotenv CHORUS_API_KEY=cho_your_key_here ``` > The transport is inferred from the `url` key — there is no `type = "http"` field in Codex's MCP schema. Auth uses `bearer_token_env_var` (Codex resolves the named env var into `Authorization: Bearer ` at connect time); Codex does **not** expand `${VAR}` inside `http_headers`, so don't put a literal key there. Use the `http_headers` table only for non-secret headers like `X-Chorus-Project`. > Easier path: install the Chorus CLI globally with `npm install -g @chorus-aidlc/chorus@0.22.0`, then run `chorus agents add --agents codex` and it will write this block (and `~/.codex/.env`) for you, plus enable the lifecycle hooks. Restart Codex CLI after configuration. ### 3. Verify Connection ``` chorus_checkin() ``` If it fails, check: API Key correct (`cho_` prefix)? URL reachable? Codex CLI restarted? ### 4. Tool Access by Preset The table below shows default tool availability for each preset (no custom permissions). Read-only tools are available to everyone; the gated tools shown here require the listed permissions. | Tool Group | Required Permission | Developer | PM | Admin | |------------|--------------------|-----------|------|-------| | `chorus_get_*` / `chorus_list_*` / `chorus_search*` | (public, read) | Yes | Yes | Yes | | `chorus_checkin` | (public) | Yes | Yes | Yes | | `chorus_add_comment` / `chorus_get_comments` | (public) | Yes | Yes | Yes | | `chorus_update_task` (field edits + status) | (public; assignee required for status) | Yes | Yes | Yes | | `chorus_claim_task` / `chorus_release_task` / `chorus_submit_for_verify` / `chorus_report_work` / `chorus_report_criteria_self_check` | `task:write` | Yes | **Yes** (0.7.0+) | Yes | | `chorus_claim_idea` / `chorus_release_idea` / `chorus_move_idea` / `chorus_pm_create_idea` / `chorus_edit_idea` / `chorus_pm_*_elaboration` | `idea:write` | No | Yes | Yes | | `chorus_pm_create_proposal` / `chorus_pm_*_proposal` / `chorus_pm_*_draft` / `chorus_create_tasks` / `chorus_pm_assign_task` | `proposal:write` | No | Yes | Yes | | `chorus_pm_create_document` / `chorus_pm_update_document` / `chorus_create_report` | `document:write` | No | Yes | Yes | | `chorus_add_reference` / `chorus_update_reference` / `chorus_remove_reference` | `document:write` | No | Yes | Yes | | `chorus_admin_create_project` / `chorus_admin_*_project_group` / `chorus_admin_move_project_to_group` | `project:write` | No | **Yes** (0.7.0+) | Yes | | `chorus_admin_approve_proposal` / `chorus_admin_close_proposal` | `proposal:admin` | No | No | Yes | | `chorus_admin_verify_task` / `chorus_admin_reopen_task` / `chorus_admin_close_task` / `chorus_mark_acceptance_criteria` / `chorus_admin_delete_task` | `task:admin` | No | No | Yes | | `chorus_admin_delete_idea` | `idea:admin` | No | No | Yes | | `chorus_admin_delete_document` | `document:admin` | No | No | Yes | ### 5. Review Agent Configuration The plugin includes three independent review agents. After proposal submission, task verification, or the last task of an idea-rooted proposal being verified, a PostToolUse hook injects context instructing the main agent to spawn the reviewer. The main agent must spawn it manually — it is NOT auto-launched. All are **enabled by default**. | Setting | Controls | Default | |---------|----------|---------| | `enableProposalReviewer` | Spawn `chorus-proposal-reviewer` after `chorus_pm_submit_proposal` | `true` (enabled) | | `enableTaskReviewer` | Spawn `chorus-task-reviewer` after `chorus_submit_for_verify` | `true` (enabled) | | `enableCodeReviewer` | Spawn `chorus-code-reviewer` over the Idea's aggregate change after its last task is verified (final ship gateway) | `true` (enabled) | To disable in the Codex port, open `/hooks` and disable the matching Chorus plugin `PostToolUse` hook, or disable the whole `chorus@chorus-plugins` plugin in `~/.codex/config.toml`. Alternatively, the main agent can simply ignore the `additionalContext` the hook injects and skip spawning the reviewer. When enabled, reviewers run as read-only sub-agents and post a VERDICT comment on the proposal/task/idea. Three possible outcomes: **PASS** (no issues), **PASS WITH NOTES** (minor non-blocking notes), or **FAIL** (BLOCKERs found). Results are advisory — they do not block approval, verification, or ship; the code-review gateway in particular is behavioral (it does not change the Idea's stored status). On a code-review FAIL, fix it via the **quick-dev** workflow (`$quick-dev`): `chorus_create_tasks` with `proposalUuid` set to the current approved proposal so the fix tasks attach to it. Group related small BLOCKERs into one cohesive task by default; split only materially large or independently testable fixes. Each fix task must self-check its acceptance criteria and pass independent task review plus admin verification. Re-run the gateway only after every fix task is successfully `done`; if there is a failed or cancelled fix task, stop and escalate instead. Disabling reduces token usage but removes the independent quality gate. ### 6. Spec mode: OpenSpec (default when usable) vs spec-lite (fallback) The SessionStart hook resolves one **spec mode** per session and prints a `## Spec Mode` section stating it. Resolution: an explicit `CHORUS_SPEC_MODE` (`lite`/`openspec`/`off`) wins; when unset, **OpenSpec is the default whenever it is usable** (`CHORUS_OPENSPEC_MODE` ≠ `off`, an `openspec/` directory at the project root, and the `openspec` CLI on `PATH`). When OpenSpec is absent or disabled, the mode falls back to **spec-lite** — a Chorus-native, git-tracked model with a durable local `.chorus/specs//spec.md` per capability (never synced) plus dated per-change folders `/-/` of Chorus-typed docs mirrored 1:1 into Chorus (see the `spec-lite` skill). `CHORUS_SPEC_MODE=off` selects free-form (no spec artifact). OpenSpec spec-driven path: `$proposal`, `$develop`, `$yolo` write `proposal.md` / `design.md` / spec deltas on disk and mirror them into Chorus drafts. **When the user wants OpenSpec on** (e.g. they ran `$chorus enable openspec` after seeing spec-lite/off in the banner), actually **enable it for them** — run whichever steps are missing, don't just describe them: ```bash npm i -g @fission-ai/openspec # 1. install the CLI if it's not on PATH (global, pure Node) openspec init --tools codex # 2. scaffold openspec/ + wire up Codex's native commands/skills ``` `openspec init` is interactive if you omit `--tools`; pass `--tools codex` to run it unattended. The spec mode is resolved **once at SessionStart**, so it can't flip mid-session — after the steps succeed, tell the user to **restart Codex**; the `## Spec Mode` section then reads `CHORUS_SPEC_MODE=openspec (…)` and the stage skills fold in the `openspec-aware` skill automatically. To turn OpenSpec off, set `CHORUS_OPENSPEC_MODE=off` — the mode then falls back to **spec-lite** (or set `CHORUS_SPEC_MODE=off` for free-form). The `## Spec Mode` section always states the resolved mode + reason. --- ## Execution Rules 1. **Always check in first** — Call `chorus_checkin()` at session start 2. **Stay in your role** — Only use tools available to your role 3. **Report progress** — Use `chorus_report_work` or `chorus_add_comment` 4. **Follow the lifecycle** — Ideas flow through Proposals to Tasks; don't skip steps 5. **Set up task dependency DAG** — Use `dependsOnDraftUuids` in task drafts to express execution order 6. **Verify before claiming** — Check available items before claiming 7. **Document decisions** — Add comments explaining your reasoning 8. **Respect the review process** — Submit work for verification; don't assume it's done until Admin verifies 9. **Interactive questions** — For confirmations/choices, send a plain-text question; Codex currently does not ship a structured radio-button tool in default mode 10. **Verify sub-agent tasks (admin team lead)** — After a worker spawned via `spawn_agent` returns, check if its task is `to_verify` and mount the reviewer skill explicitly: `spawn_agent({items:[{type:"skill", path:"chorus:chorus-task-reviewer"}, {type:"text", text:"Review task and post VERDICT."}]})`. Wait only because verification depends on the verdict, then close the reviewer thread. Tasks in `to_verify` do NOT unblock downstream — only `done` does. --- ## Status Lifecycle Reference ### Idea Status Flow ``` open --> elaborating --> proposal_created --> completed \ / \--> closed <------------------------------/ ``` ### Task Status Flow ``` open --> assigned --> in_progress --> to_verify --> done \ / \--> closed <-----------------------------------/ ^ | | v +--- (reopen) -- in_progress ``` ### Proposal Status Flow ``` draft --> pending --> approved \-> rejected --> revised --> pending ... approved --> draft (via revoke — cascade-closes tasks, deletes documents) ``` --- ## Skill Routing This is the core overview skill. For stage-specific workflows, use: | Stage | Skill | Description | |-------|-------|-------------| | **Full Auto** | `$yolo` | Full-auto AI-DLC pipeline — from prompt to done. Automates Idea → Proposal → Execute → Verify with adversarial reviewers | | **Orchestration** | `$orchestrate` | Coordinate OTHER agents & humans across the lifecycle — delegate ideas (`chorus_pm_assign_idea`) & tasks, fan a theme out to child ideas, run independent reviewers, and gatekeep the proposal/verify gates | | **Quick Dev** | `$quick-dev` | Skip Idea→Proposal, create tasks directly, execute, and verify | | **Ideation** | `$idea` | Claim Ideas, run elaboration rounds, prepare for proposal | | **Research** | `$research` | Optional bounded factual checks shared by Idea and Proposal; explicit Tracker Research saves findings to the Idea and returns without advancing lifecycle | | **Planning** | `$proposal` | Create Proposals with document & task drafts, manage dependency DAG, submit for review | | **Development** | `$develop` | Claim Tasks, report work, and coordinate sub-agent workers | | **Review** | `$review` | Approve/reject Proposals, verify Tasks, project governance | | **Docs** | `$docs` | Consult the live Chorus documentation site to answer product-usage questions — UI workflow, agent/plugin setup, API/MCP, deployment, operations | | **OpenSpec mode** | `openspec-aware` | **Shared sub-procedure** invoked by `proposal`, `develop`, `yolo` when the resolved spec mode is a usable OpenSpec (the default when `openspec/` + CLI present and not disabled). Scaffolds `openspec/changes//` on disk and mirrors files into Chorus document drafts via `chorus mcp call --arg-file` (bash `chorus-mcp-call.sh` wrapper as fallback). See `~/.codex/skills/openspec-aware/SKILL.md`. | | **spec-lite mode** | `spec-lite` | **Shared sub-procedure** and the fallback when OpenSpec isn't usable (or `CHORUS_SPEC_MODE=lite`). Durable local `.chorus/specs//spec.md` (never synced) + dated per-change folders of Chorus-typed docs mirrored 1:1 into Chorus via `--arg-file`. No CLI/validation. See `~/.codex/skills/spec-lite/SKILL.md`. | ### Getting Started 1. Call `chorus_checkin()` to learn your role and assignments 2. Based on your role, use the appropriate skill: - **Full Auto** → `$yolo` — give a prompt, agent handles everything (requires Admin-preset permissions: write on every resource + approve/verify admin bits) - PM Agent → `$idea` then `$proposal` - Developer Agent → `$develop` - Admin Agent → `$review` (also has access to all PM and Developer tools)