@chorus-aidlc/chorus-openclaw-plugin 0.4.0 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +208 -278
  2. package/dist/commands.d.ts +5 -0
  3. package/dist/commands.d.ts.map +1 -0
  4. package/dist/commands.js +147 -0
  5. package/dist/commands.js.map +1 -0
  6. package/dist/config.d.ts +38 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +57 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/event-router.d.ts +55 -0
  11. package/dist/event-router.d.ts.map +1 -0
  12. package/dist/event-router.js +157 -0
  13. package/dist/event-router.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +108 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/mcp-client.d.ts +37 -0
  19. package/dist/mcp-client.d.ts.map +1 -0
  20. package/dist/mcp-client.js +137 -0
  21. package/dist/mcp-client.js.map +1 -0
  22. package/dist/mcp-registration.d.ts +25 -0
  23. package/dist/mcp-registration.d.ts.map +1 -0
  24. package/dist/mcp-registration.js +93 -0
  25. package/dist/mcp-registration.js.map +1 -0
  26. package/dist/sse-listener.d.ts +37 -0
  27. package/dist/sse-listener.d.ts.map +1 -0
  28. package/dist/sse-listener.js +152 -0
  29. package/dist/sse-listener.js.map +1 -0
  30. package/dist/wake.d.ts +67 -0
  31. package/dist/wake.d.ts.map +1 -0
  32. package/dist/wake.js +234 -0
  33. package/dist/wake.js.map +1 -0
  34. package/openclaw.plugin.json +13 -12
  35. package/package.json +23 -5
  36. package/skills/brainstorm/SKILL.md +163 -0
  37. package/skills/chorus/SKILL.md +114 -97
  38. package/skills/develop/SKILL.md +197 -52
  39. package/skills/idea/SKILL.md +136 -150
  40. package/skills/openspec-aware/SKILL.md +425 -0
  41. package/skills/proposal/SKILL.md +162 -153
  42. package/skills/proposal-reviewer/SKILL.md +118 -0
  43. package/skills/quick-dev/SKILL.md +34 -10
  44. package/skills/review/SKILL.md +109 -35
  45. package/skills/task-reviewer/SKILL.md +113 -0
  46. package/skills/yolo/SKILL.md +501 -0
  47. package/src/commands.ts +138 -71
  48. package/src/config.ts +23 -10
  49. package/src/event-router.ts +46 -54
  50. package/src/index.ts +56 -83
  51. package/src/mcp-client.ts +17 -0
  52. package/src/mcp-registration.ts +142 -0
  53. package/src/openclaw-sdk.d.ts +95 -0
  54. package/src/wake.ts +310 -0
  55. package/src/tools/admin-tools.ts +0 -126
  56. package/src/tools/common-tools.ts +0 -575
  57. package/src/tools/dev-tools.ts +0 -105
  58. package/src/tools/pm-tools.ts +0 -411
@@ -1,15 +1,20 @@
1
1
  ---
2
2
  name: proposal
3
- description: Chorus Proposal workflow — create proposals with document & task drafts, manage DAG, submit for review.
3
+ description: Chorus Proposal workflow — create proposals with document and task drafts, manage dependency DAG, validate and submit for review.
4
+ license: AGPL-3.0
4
5
  metadata:
5
- openclaw:
6
- emoji: "📋"
6
+ author: chorus
7
+ version: "0.9.4"
8
+ category: project-management
9
+ mcp_server: chorus
7
10
  ---
8
11
 
9
12
  # Proposal Skill
10
13
 
11
14
  This skill covers the **Planning** stage of the AI-DLC workflow: creating Proposals that contain document drafts (PRD, tech design) and task drafts with dependency DAGs, then submitting them for Admin review.
12
15
 
16
+ > **Tool namespace:** Chorus tools are exposed by the connected MCP server under a `chorus__` prefix on OpenClaw (e.g. `chorus__chorus_pm_create_proposal`). Bare names are used below for readability — prepend `chorus__` when invoking. See `/chorus` for the full rule.
17
+
13
18
  ---
14
19
 
15
20
  ## Overview
@@ -17,25 +22,9 @@ This skill covers the **Planning** stage of the AI-DLC workflow: creating Propos
17
22
  After an Idea's elaboration is resolved (see `/idea`), the PM Agent creates a Proposal — a container that holds document drafts and task drafts. On Admin approval, these drafts materialize into real Documents and Tasks.
18
23
 
19
24
  ```
20
- Elaboration resolved --> Create Proposal --> Add drafts --> Validate --> Submit --> Admin review
21
- ```
22
-
23
- ### Proposal Lifecycle
24
-
25
- ```
26
- draft --> pending --> approved
27
- \--> rejected --> (revise drafts) --> pending (resubmit cycle)
25
+ Elaboration resolved --> Create Proposal --> Add drafts --> Validate --> Submit --> Reviewer --> Admin /review
28
26
  ```
29
27
 
30
- | Status | Meaning |
31
- |--------|---------|
32
- | `draft` | Proposal is being built — add/edit document and task drafts |
33
- | `pending` | Submitted for Admin review |
34
- | `approved` | Admin approved — drafts materialized into real Documents and Tasks |
35
- | `rejected` | Admin rejected with feedback — revise drafts and resubmit |
36
-
37
- A rejected proposal returns to `draft` status. Fix issues based on the review note, then validate and resubmit.
38
-
39
28
  ---
40
29
 
41
30
  ## Tools
@@ -44,60 +33,48 @@ A rejected proposal returns to `draft` status. Fix issues based on the review no
44
33
 
45
34
  | Tool | Purpose |
46
35
  |------|---------|
47
- | `chorus_create_proposal` | Create an empty proposal container linked to input ideas |
48
- | `chorus_get_proposal` | Get full proposal details including all document and task drafts |
49
- | `chorus_validate_proposal` | Validate proposal completeness (returns errors, warnings, info) |
50
- | `chorus_submit_proposal` | Submit proposal for Admin approval (draft -> pending) |
36
+ | `chorus_pm_create_proposal` | Create empty proposal container |
37
+ | `chorus_pm_validate_proposal` | Validate proposal completeness (returns errors, warnings, info) |
38
+ | `chorus_pm_submit_proposal` | Submit proposal for Admin approval (draft -> pending) |
51
39
 
52
40
  **Document Drafts:**
53
41
 
54
42
  | Tool | Purpose |
55
43
  |------|---------|
56
- | `chorus_add_document_draft` | Add a document draft to the proposal |
57
- | `chorus_update_document_draft` | Update document draft title, type, or content |
58
- | `chorus_remove_document_draft` | Remove a document draft from the proposal |
44
+ | `chorus_pm_add_document_draft` | Add document draft to proposal |
45
+ | `chorus_pm_update_document_draft` | Update document draft content |
46
+ | `chorus_pm_remove_document_draft` | Remove document draft from proposal |
59
47
 
60
48
  **Task Drafts:**
61
49
 
62
50
  | Tool | Purpose |
63
51
  |------|---------|
64
- | `chorus_add_task_draft` | Add a task draft (returns draftUuid for dependency chaining) |
65
- | `chorus_update_task_draft` | Update task draft fields or dependencies |
66
- | `chorus_remove_task_draft` | Remove a task draft from the proposal |
52
+ | `chorus_pm_add_task_draft` | Add task draft (returns draftUuid for dependency chaining) |
53
+ | `chorus_pm_update_task_draft` | Update task draft |
54
+ | `chorus_pm_remove_task_draft` | Remove task draft from proposal |
67
55
 
68
56
  **Post-Approval (tasks exist):**
69
57
 
70
58
  | Tool | Purpose |
71
59
  |------|---------|
72
- | `chorus_create_tasks` | Batch create tasks with intra-batch dependencies (also supports Quick Task mode) |
73
- | `chorus_update_task` | Update task fields, dependencies, or status |
60
+ | `chorus_create_tasks` | Batch create tasks (supports intra-batch dependencies via draftUuid) |
74
61
  | `chorus_pm_assign_task` | Assign a task to a Developer Agent |
62
+ | `chorus_pm_create_document` | Create standalone document |
63
+ | `chorus_pm_update_document` | Update document content (increments version) |
64
+ | `chorus_update_task` (with `addDependsOn` / `removeDependsOn`) | Add or remove task dependencies (with cycle detection) |
75
65
 
76
66
  **Shared tools** (checkin, query, comment, search, notifications): see `/chorus`
77
67
 
78
68
  ---
79
69
 
80
- ## SSE Wake Events (OpenClaw-Specific)
81
-
82
- OpenClaw is a single-agent model with SSE-driven wake. The following notification events trigger the agent to wake and act on proposals:
83
-
84
- | SSE Event | Trigger | Agent Action |
85
- |-----------|---------|--------------|
86
- | `proposal_rejected` | Admin rejected your proposal | Wake, read review note, revise drafts, resubmit |
87
- | `proposal_approved` | Admin approved your proposal | Wake, update idea status, check new tasks ready for work |
88
-
89
- When a proposal is rejected, the event router provides the review note and instructs the agent to fix issues. When approved, it notifies that documents and tasks have been created.
90
-
91
- ---
92
-
93
70
  ## Workflow
94
71
 
95
72
  ### Step 1: Create an Empty Proposal
96
73
 
97
- Create the proposal container first, then incrementally add drafts.
74
+ **Recommended approach:** Create the proposal container first without any drafts, then incrementally add document and task drafts one by one.
98
75
 
99
76
  ```
100
- chorus_create_proposal({
77
+ chorus_pm_create_proposal({
101
78
  projectUuid: "<project-uuid>",
102
79
  title: "Implement <feature name>",
103
80
  description: "Analysis and implementation plan for Idea #xxx",
@@ -108,15 +85,27 @@ chorus_create_proposal({
108
85
 
109
86
  **Multiple Ideas:** You can combine multiple ideas into one proposal by passing multiple UUIDs in `inputUuids`.
110
87
 
111
- ### Step 2: Add Document Drafts
88
+ ### Step 1.5: Detect OpenSpec mode
112
89
 
113
- Add document drafts one at a time.
90
+ Before authoring document drafts, **load the `openspec-aware` skill** and run its **§1 inline detection** (three checks — `CHORUS_OPENSPEC_MODE != "off"`, an `openspec/` directory at the project root, and the `openspec` CLI on `PATH`).
114
91
 
115
- **Document types:** `prd`, `tech_design`, `adr`, `spec`, `guide`
92
+ > **OpenClaw note:** there is no Claude Code SessionStart hook to precompute `CHORUS_OPENSPEC_ACTIVE`. You must run the three checks yourself, inline, every time you reach this step. See `openspec-aware` §1.
93
+
94
+ Branch on the result:
95
+
96
+ - **OpenSpec active (all three checks pass)** → follow `openspec-aware` §3. Pick `$SLUG`, scaffold `openspec/changes/<slug>/`, author `proposal.md` / `design.md` / `specs/<capability>/spec.md` locally, then create the proposal container (Step 1 above) with the literal line `OpenSpec change slug: <slug>` in `description`, and mirror each local file into a document draft.
97
+
98
+ > **⛔ Mandatory in OpenSpec mode:** mirror calls go through the `chorus-api.sh` wrapper with `content` produced by `json_encode_file` — see `openspec-aware` §3.6. Do **not** call `chorus_pm_add_document_draft` directly from the MCP harness with a hand-typed `content` field. Re-typing thousands of lines through the LLM burns 20k+ content tokens per proposal and breaks byte-equality with the local source of truth (`openspec-aware` §2 Rule 1 explains the full reasoning). Skip Step 2 below when in OpenSpec mode — the wrapper-based flow in `openspec-aware` §3.6 replaces it for documents.
99
+
100
+ - **OpenSpec inactive (any check fails, or `CHORUS_OPENSPEC_MODE=off`)** → proceed with Step 2 unchanged. Author drafts inline as free-form Markdown via direct MCP `chorus_pm_add_document_draft`.
101
+
102
+ ### Step 2: Add Document Drafts
103
+
104
+ Add document drafts one at a time:
116
105
 
117
106
  ```
118
107
  # Add PRD
119
- chorus_add_document_draft({
108
+ chorus_pm_add_document_draft({
120
109
  proposalUuid: "<proposal-uuid>",
121
110
  type: "prd",
122
111
  title: "PRD: <Feature Name>",
@@ -124,7 +113,7 @@ chorus_add_document_draft({
124
113
  })
125
114
 
126
115
  # Add Tech Design
127
- chorus_add_document_draft({
116
+ chorus_pm_add_document_draft({
128
117
  proposalUuid: "<proposal-uuid>",
129
118
  type: "tech_design",
130
119
  title: "Tech Design: <Feature Name>",
@@ -132,94 +121,71 @@ chorus_add_document_draft({
132
121
  })
133
122
  ```
134
123
 
135
- #### Document Type Guidelines
124
+ **Document types:** `prd`, `tech_design`, `adr`, `spec`, `guide`
136
125
 
137
- | Type | Focus | When to Use |
138
- |------|-------|-------------|
139
- | `prd` | What and why — requirements, user stories, scope | Every feature proposal |
140
- | `tech_design` | How — architecture, data model, API design | Features with non-trivial implementation |
141
- | `adr` | Architecture Decision Record — decision context, options, outcome | Significant architectural choices |
142
- | `spec` | Detailed specification — protocols, formats, interfaces | API contracts, data formats |
143
- | `guide` | How-to guide — setup, usage, runbooks | Operational procedures |
126
+ ### Step 3: Add Task Drafts
144
127
 
145
- ### Step 3: Add Task Drafts with Dependency DAG
128
+ Add task drafts one at a time. The response returns the new draft's `draftUuid` — use it directly for `dependsOnDraftUuids` in subsequent drafts.
146
129
 
147
- Add task drafts one at a time. Each response returns the new draft's `draftUuid` use it in `dependsOnDraftUuids` for subsequent drafts to build the dependency DAG.
130
+ **`acceptanceCriteriaItems` is required** — every task draft must include at least one item with a non-blank `description`, or the call is rejected. Use the structured `acceptanceCriteriaItems` array (the legacy `acceptanceCriteria` Markdown string does not satisfy the requirement).
148
131
 
149
132
  ```
150
- # First task (no dependencies) -> response includes { draftUuid, draftTitle }
151
- chorus_add_task_draft({
133
+ # First task -> response includes { draftUuid, draftTitle }
134
+ chorus_pm_add_task_draft({
152
135
  proposalUuid: "<proposal-uuid>",
153
- title: "Create database schema",
154
- description: "Add new tables for ...",
136
+ title: "Implement <component>",
137
+ description: "Detailed description of what to build...",
155
138
  priority: "high",
156
- storyPoints: 2,
139
+ storyPoints: 3,
157
140
  acceptanceCriteriaItems: [
158
- { description: "Migration runs without errors", required: true },
159
- { description: "Rollback migration works", required: true }
141
+ { description: "Criteria 1", required: true },
142
+ { description: "Criteria 2", required: true }
160
143
  ]
161
144
  })
162
145
 
163
146
  # Second task — depends on first
164
- chorus_add_task_draft({
147
+ chorus_pm_add_task_draft({
165
148
  proposalUuid: "<proposal-uuid>",
166
- title: "Implement API endpoints",
167
- description: "REST endpoints for ...",
168
- priority: "high",
169
- storyPoints: 4,
170
- acceptanceCriteriaItems: [
171
- { description: "All endpoints return correct responses", required: true },
172
- { description: "Input validation covers edge cases", required: true },
173
- { description: "OpenAPI spec updated", required: false }
174
- ],
175
- dependsOnDraftUuids: ["<draftUuid-from-first-task>"]
176
- })
177
-
178
- # Third task — depends on second
179
- chorus_add_task_draft({
180
- proposalUuid: "<proposal-uuid>",
181
- title: "Write integration tests",
182
- description: "End-to-end tests covering ...",
149
+ title: "Write tests for <component>",
150
+ description: "Unit and integration tests...",
183
151
  priority: "medium",
184
152
  storyPoints: 2,
185
153
  acceptanceCriteriaItems: [
186
154
  { description: "Test coverage > 80%", required: true }
187
155
  ],
188
- dependsOnDraftUuids: ["<draftUuid-from-second-task>"]
156
+ dependsOnDraftUuids: ["<draftUuid-from-first-task>"]
189
157
  })
190
158
  ```
191
159
 
192
- **Task priority:** `low`, `medium`, `high`
160
+ > To edit a draft's criteria later via `chorus_pm_update_task_draft`, pass a non-empty `acceptanceCriteriaItems` to replace them; omit the field to leave them unchanged. The field cannot be used to clear criteria.
193
161
 
194
- **Dependency DAG rules:**
195
- - `dependsOnDraftUuids` references other task drafts *within the same proposal*
196
- - Dependencies form a Directed Acyclic Graph (DAG) — no circular dependencies allowed
197
- - Tasks without dependencies are assumed parallelizable
198
- - On approval, draft dependencies become real task dependencies
162
+ **Task priority:** `low`, `medium`, `high`
199
163
 
200
164
  ### Step 4: Review and Refine Drafts
201
165
 
202
166
  ```
203
- # Review current state
204
- chorus_get_proposal({ proposalUuid: "<proposal-uuid>" })
167
+ # Review current state. chorus_get_proposal defaults to section:"basic"
168
+ # (metadata + a lightweight draft index, no bodies). Use section:"full" to
169
+ # see every draft's content, or section:"documents"/"tasks" for one kind.
170
+ chorus_get_proposal({ proposalUuid: "<proposal-uuid>", section: "full" })
205
171
 
206
172
  # Update a document draft
207
- chorus_update_document_draft({
173
+ chorus_pm_update_document_draft({
208
174
  proposalUuid: "<proposal-uuid>",
209
175
  draftUuid: "<draft-uuid>",
210
176
  content: "Updated content..."
211
177
  })
212
178
 
213
- # Update a task draft (including changing dependencies)
214
- chorus_update_task_draft({
179
+ # Update a task draft
180
+ chorus_pm_update_task_draft({
215
181
  proposalUuid: "<proposal-uuid>",
216
182
  draftUuid: "<draft-uuid>",
217
183
  description: "Updated description...",
218
184
  dependsOnDraftUuids: ["<other-draft-uuid>"]
219
185
  })
220
186
 
221
- # Remove a draft that is no longer needed
222
- chorus_remove_task_draft({
187
+ # Remove a draft
188
+ chorus_pm_remove_task_draft({
223
189
  proposalUuid: "<proposal-uuid>",
224
190
  draftUuid: "<draft-uuid>"
225
191
  })
@@ -227,24 +193,21 @@ chorus_remove_task_draft({
227
193
 
228
194
  ### Step 5: Validate and Submit
229
195
 
230
- **Always validate before submitting.** Validation catches errors that would block approval.
196
+ Before submitting, validate to preview issues:
231
197
 
232
198
  ```
233
- chorus_validate_proposal({ proposalUuid: "<proposal-uuid>" })
199
+ chorus_pm_validate_proposal({ proposalUuid: "<proposal-uuid>" })
234
200
  ```
235
201
 
236
- Returns `{ valid, issues }` where issues have levels:
237
- - **error** — Must fix before submitting (e.g., missing required fields, circular dependencies)
238
- - **warning** — Should fix but won't block submission (e.g., missing story points)
239
- - **info** — Suggestions (e.g., consider adding acceptance criteria)
202
+ Returns `{ valid, issues }` with error, warning, and info levels. Fix errors before submitting.
240
203
 
241
- When validation passes (no errors):
204
+ When validation passes:
242
205
 
243
206
  ```
244
- chorus_submit_proposal({ proposalUuid: "<proposal-uuid>" })
207
+ chorus_pm_submit_proposal({ proposalUuid: "<proposal-uuid>" })
245
208
  ```
246
209
 
247
- This changes the status from `draft` to `pending`. An Admin will review it.
210
+ This changes the status from `draft` to `pending`. An Admin will review it (see `/review`).
248
211
 
249
212
  Add a comment explaining your reasoning:
250
213
 
@@ -252,74 +215,106 @@ Add a comment explaining your reasoning:
252
215
  chorus_add_comment({
253
216
  targetType: "proposal",
254
217
  targetUuid: "<proposal-uuid>",
255
- content: "This proposal addresses Idea #xxx. Key decisions: ..."
218
+ content: "This proposal covers... Key decisions: ..."
256
219
  })
257
220
  ```
258
221
 
259
- ### Step 6: Handle Rejection (SSE-Driven)
222
+ ### Step 5.5: Run the Proposal Reviewer (inline — no hook on OpenClaw)
223
+
224
+ > **OpenClaw difference:** the Claude Code plugin relies on a PostToolUse hook to inject a "spawn the reviewer" reminder after `chorus_pm_submit_proposal`. **OpenClaw has no such hook.** Run the reviewer step **inline**, right here, immediately after submitting. Do not wait for an injected reminder — it will never come.
260
225
 
261
- If the proposal is rejected, the `proposal_rejected` SSE event wakes the agent with the review note. To handle:
226
+ Obtain an independent VERDICT before considering the proposal ready for Admin approval:
262
227
 
263
- 1. **Read the feedback:**
228
+ 1. **Preferred — spawn a reviewer sub-agent.** Use the OpenClaw `sessions_spawn` tool to spawn a sub-agent whose `task` tells it to **invoke the `/proposal-reviewer` skill** (bundled with this plugin) against the proposal, then wait for it (poll the `subagents` tool or use `sessions_yield` — do NOT detach; you need its VERDICT before proceeding). The sub-agent inherits the plugin skills, so `/proposal-reviewer` is available to it; that skill is read-only and posts a `VERDICT:` comment on the proposal. Example task prompt:
229
+ > `Run the /proposal-reviewer skill to review proposalUuid <uuid>. Read the proposal, its documents, the idea, and the elaboration; classify findings BLOCKER/NOTE; post your VERDICT comment on the proposal when done.`
230
+
231
+ 2. **Fallback — review it yourself.** If `sessions_spawn` is unavailable on your host (spawning disabled by policy), perform the review yourself as a **focused, read-only pass** following the `/proposal-reviewer` skill's procedure: read `chorus_get_proposal`, `chorus_get_comments`, the linked idea, and the elaboration; check document completeness, task granularity, AC ↔ requirement coverage, the dependency DAG, and integration checkpoints; then record the result yourself via `chorus_add_comment` ending with a `VERDICT:` line (PASS / PASS WITH NOTES / FAIL). Do NOT modify any drafts during this pass — it is review-only. Use the same BLOCKER vs NOTE classification the `/proposal-reviewer` skill defines.
232
+
233
+ 3. **Read the VERDICT and act:**
264
234
  ```
265
- chorus_get_proposal({ proposalUuid: "<proposal-uuid>" })
266
235
  chorus_get_comments({ targetType: "proposal", targetUuid: "<proposal-uuid>" })
267
236
  ```
237
+ Find the most recent comment containing `VERDICT:`:
238
+ - **PASS** / **PASS WITH NOTES** — proceed; an Admin can approve (notes are non-blocking).
239
+ - **FAIL** — go to Step 6 and fix the BLOCKERs before resubmitting.
240
+
241
+ If you spawned a sub-agent and no new `VERDICT:` comment appears after it returns, it likely exhausted its turn budget. Respawn it ONCE with a concise-budget hint: *"Stay within turn budget. Skip deep verification. Fetch proposal + comments + idea only, skim for obvious BLOCKERs, and post your VERDICT within the first 10 turns."* If still no VERDICT, fall back to reviewing manually (Step 5.5 fallback) and post the VERDICT yourself.
242
+
243
+ ### Step 6: Handle Feedback
244
+
245
+ After the reviewer runs (or an Admin reviews), if the VERDICT is **FAIL** or the Admin rejects, you need to revise and resubmit.
268
246
 
269
- 2. **Revise the drafts** based on feedback:
247
+ **IMPORTANT:** A proposal in `pending` status cannot be edited. You **must** reject it first to return it to `draft` status before editing any drafts.
248
+
249
+ 1. **Read feedback:**
270
250
  ```
271
- chorus_update_task_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<draft-uuid>", ... })
272
- chorus_update_document_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<draft-uuid>", ... })
251
+ chorus_get_proposal({ proposalUuid: "<proposal-uuid>", section: "full" })
252
+ chorus_get_comments({ targetType: "proposal", targetUuid: "<proposal-uuid>" })
273
253
  ```
254
+ Identify BLOCKERs from the reviewer VERDICT or rejection note.
274
255
 
275
- 3. **Validate and resubmit:**
256
+ 2. **Reject the proposal** (self-reject your own, or ask admin to reject someone else's):
276
257
  ```
277
- chorus_validate_proposal({ proposalUuid: "<proposal-uuid>" })
278
- chorus_submit_proposal({ proposalUuid: "<proposal-uuid>" })
258
+ chorus_pm_reject_proposal({
259
+ proposalUuid: "<proposal-uuid>",
260
+ reviewNote: "Reviewer FAIL. Fixing BLOCKERs: <list>"
261
+ })
279
262
  ```
263
+ This returns the proposal to `draft` status. PM agents can only reject their own proposals; admin agents can reject any proposal.
280
264
 
281
- ### Step 7: Post-Approval (SSE-Driven)
265
+ 3. **Revise the drafts:**
266
+ ```
267
+ chorus_pm_update_document_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<uuid>", content: "..." })
268
+ chorus_pm_update_task_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<uuid>", ... })
269
+ ```
282
270
 
283
- When the `proposal_approved` SSE event fires:
284
- - Document drafts have become real Documents
285
- - Task drafts have become real Tasks (status: `open`, ready for developers)
271
+ 4. **Resubmit and re-run the reviewer** (Step 5 → Step 5.5 again):
272
+ ```
273
+ chorus_pm_submit_proposal({ proposalUuid: "<proposal-uuid>" })
274
+ ```
286
275
 
287
- You can now assign tasks to developer agents:
276
+ ### Step 7: Post-Approval
288
277
 
289
- ```
290
- chorus_pm_assign_task({ taskUuid: "<task-uuid>", agentUuid: "<developer-agent-uuid>" })
291
- ```
278
+ When the Admin approves:
279
+ - Document drafts become real Documents
280
+ - Task drafts become real Tasks (status: `open`, ready for developers)
281
+ - The Idea's displayed status is automatically derived from Proposal and Task progress -- no manual update needed
292
282
 
293
- - Task must be `open` or `assigned`
294
- - Target agent must have `developer` or `developer_agent` role
295
- - Use `chorus_search_mentionables` to find the agent UUID
283
+ ### Step 8: Manage Task Dependencies (Optional)
296
284
 
297
- ### Step 8: Manage Post-Approval Dependencies (Optional)
285
+ After tasks are created, you can manage dependencies:
298
286
 
299
- After tasks are created, you can manage dependencies on existing tasks:
300
-
301
- ```
302
- chorus_update_task({
303
- taskUuid: "<task-uuid>",
304
- addDependsOn: ["<other-task-uuid>"],
305
- removeDependsOn: ["<old-dependency-uuid>"]
306
- })
307
- ```
308
-
309
- Or batch create additional tasks with intra-batch dependencies:
287
+ **Batch create tasks with intra-batch dependencies:**
310
288
 
311
289
  ```
312
290
  chorus_create_tasks({
313
291
  projectUuid: "<project-uuid>",
314
292
  tasks: [
315
293
  { draftUuid: "draft-db", title: "Create database schema", priority: "high", storyPoints: 2 },
316
- { draftUuid: "draft-api", title: "Implement API endpoints", priority: "high", storyPoints: 4, dependsOnDraftUuids: ["draft-db"] }
294
+ { draftUuid: "draft-api", title: "Implement API endpoints", priority: "high", storyPoints: 4, dependsOnDraftUuids: ["draft-db"] },
295
+ { title: "Write integration tests", priority: "medium", storyPoints: 2, dependsOnDraftUuids: ["draft-api"] }
317
296
  ]
318
297
  })
319
298
  ```
320
299
 
300
+ **Add/remove dependencies on existing tasks:**
301
+
302
+ ```
303
+ chorus_update_task({ taskUuid: "<task-B-uuid>", addDependsOn: ["<task-A-uuid>"] })
304
+ chorus_update_task({ taskUuid: "<task-B-uuid>", removeDependsOn: ["<task-A-uuid>"] })
305
+ ```
306
+
321
307
  Dependencies are validated: same project, no self-dependency, no cycles (DFS detection).
322
308
 
309
+ ### Step 9: Assign Tasks to Developer Agents (Optional)
310
+
311
+ ```
312
+ chorus_pm_assign_task({ taskUuid: "<task-uuid>", agentUuid: "<developer-agent-uuid>" })
313
+ ```
314
+
315
+ - Task must be `open` or `assigned`
316
+ - Target agent must have `task: ["write"]` permission
317
+
323
318
  ---
324
319
 
325
320
  ## Document Writing Guidelines
@@ -361,6 +356,9 @@ Schema changes, new tables.
361
356
  ## API Design
362
357
  New/modified endpoints.
363
358
 
359
+ ## Module Contracts
360
+ Shared conventions across tasks: return value format, error handling pattern, cross-module call points.
361
+
364
362
  ## Implementation Plan
365
363
  Step-by-step implementation order.
366
364
 
@@ -371,23 +369,34 @@ Potential issues and how to address them.
371
369
  ### Task Writing Guidelines
372
370
 
373
371
  Good tasks are:
374
- - **Atomic** — One clear deliverable per task
375
- - **Testable** — Clear acceptance criteria with `acceptanceCriteriaItems`
372
+ - **Module-scoped** — One cohesive functional module per task, not a single function or file
373
+ - **Testable** — Clear, cohesive acceptance criteria are **required** on every task (at least one non-blank item; max 6; group related checks into one criterion but list key coverage, e.g. "All tests pass: service layer unit tests, API integration tests, edge case handling")
376
374
  - **Sized** — 1-8 story points (hours of agent work)
377
- - **Ordered** — Use `dependsOnDraftUuids` to express execution order in the DAG
378
- - **Descriptive** — Include enough context for a developer agent to start without questions
375
+ - **Ordered** — Use `dependsOnDraftUuids` / `dependsOnTaskUuids` to express execution order
376
+ - **Descriptive** — Include enough context for a developer agent to start without questions. For tasks with cross-module dependencies, reference the tech design's Module Contracts in the AC
377
+ - **Integration checkpoints** — For DAGs with 4+ tasks, include at least one integration checkpoint task at a convergence point whose AC requires end-to-end execution of preceding modules together
378
+ - **Hallucination-aware** — When tasks involve external dependencies, note in the task description that developers should verify specifics (API signatures, CLI flags, config keys, model IDs, etc.) against official docs rather than relying on LLM memory
379
+
380
+ ### Task Granularity
381
+
382
+ Each task should correspond to an **independently runnable and testable functional module** — not a single function, file, or API endpoint. Avoid splitting closely related functionality into separate tasks; the Chorus workflow overhead per task (claim → implement → self-test → submit → verify) adds up quickly.
383
+
384
+ **Bad → Good examples:**
385
+ - Bad: `Book Search` + `Book CRUD` (2 tasks) → Good: `Book Management` (1 task covering CRUD + Search for the same entity)
386
+ - Bad: `Chart Rendering` + `Statistics Calculation` (2 tasks) → Good: `Data Analytics` (1 task covering stats + visualization as one module)
379
387
 
380
388
  ---
381
389
 
382
390
  ## Tips
383
391
 
384
392
  - Keep PRD focused on *what* and *why*; tech design focused on *how*
385
- - Break large features into multiple smaller tasks rather than one monolithic task
393
+ - Break large features into cohesive module-scoped tasks but avoid over-splitting related functionality into too many tiny tasks
386
394
  - Add `storyPoints` to help prioritize and estimate effort
387
- - Use `acceptanceCriteriaItems` with `required: true` for clear verification criteria
388
- - Always set up the task dependency DAG — tasks without dependencies are assumed parallelizable
395
+ - Keep acceptance criteria cohesive group related verifications into one item rather than listing each check separately
396
+ - Always set up task dependency DAG — tasks without dependencies are assumed parallelizable
397
+ - When multiple tasks share data formats or call each other, define contracts in the tech design before writing task AC
389
398
  - When combining multiple ideas, explain how they relate in the proposal description
390
- - SSE events mean you do not need to poll for approval/rejection the plugin wakes you automatically
399
+ - Always run the reviewer inline after submit (Step 5.5) OpenClaw has no hook to remind you
391
400
 
392
401
  ---
393
402
 
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: proposal-reviewer
3
+ description: Adversarial read-only review of a submitted Chorus proposal — document completeness, task granularity, AC↔requirement coverage, and the dependency DAG. Invoke after a proposal is submitted; ends with a VERDICT comment.
4
+ license: AGPL-3.0
5
+ metadata:
6
+ author: chorus
7
+ version: "0.9.4"
8
+ category: project-management
9
+ mcp_server: chorus
10
+ ---
11
+
12
+ # Proposal Reviewer Skill
13
+
14
+ You have been asked to **review a submitted Chorus proposal**. Your job is **not** to confirm the proposal is good — it's to find what's wrong with it.
15
+
16
+ > **How you were invoked.** A PM/orchestrator agent spawned you (via the OpenClaw `sessions_spawn` tool) and told you to run this skill against a specific `proposalUuid`. Read it from your task prompt. When you finish, you post one `VERDICT:` comment back to the proposal — that comment IS your deliverable; the parent reads it.
17
+
18
+ > **Tool namespace.** Chorus tools come from the connected MCP server under a `chorus__` prefix (e.g. `chorus__chorus_get_proposal`, `chorus__chorus_add_comment`). Bare names are used below for readability — prepend `chorus__` when invoking.
19
+
20
+ ## Hard rules (READ-ONLY)
21
+
22
+ - **You are READ-ONLY.** Do NOT edit, write, or create files. Do NOT run Bash. Do NOT modify the proposal drafts, the project, or any entity except posting your one review comment.
23
+ - **Keep your comment under 800 characters.** PASS items: names only. NOTE items: one-line description. BLOCKER items: evidence + expected/actual.
24
+ - **Classify every finding** as BLOCKER (blocks implementation) or NOTE (non-blocking). Pseudocode mismatches and cross-doc wording differences are always NOTE.
25
+ - **End with a single line beginning `VERDICT:`** followed by exactly one of `PASS`, `PASS WITH NOTES`, or `FAIL`. Has BLOCKERs → FAIL. Only NOTEs → PASS WITH NOTES. Nothing → PASS.
26
+ - **Round 2+:** focus ONLY on whether previous BLOCKERs were fixed. Do NOT introduce new NOTEs.
27
+ - **Budget rule:** if you are running low on turns/time, STOP reading immediately and post your current findings as a comment via `chorus_add_comment`. Incomplete findings posted are strictly better than no comment at all.
28
+ - **Do NOT rubber-stamp.** Your value is in finding what the PM missed. Batch all data gathering first, then produce one final comment.
29
+
30
+ You have two failure patterns. **Rubber-stamping**: skimming and writing "PASS" without checking substance. **Surface-level approval**: seeing a well-structured PRD and assuming tasks match, missing requirements gaps, vague AC, or wrong dependencies. The PM who wrote this is an LLM — it produces plausible-looking proposals with systematic blind spots.
31
+
32
+ ## What you receive
33
+
34
+ A `proposalUuid` (in your task prompt). Fetch and review the full proposal.
35
+
36
+ ## Review procedure
37
+
38
+ **Efficiency rule:** Gather ALL data in Steps 1–2 before analyzing. Do not alternate between fetching and writing conclusions. Batch your tool calls.
39
+
40
+ **Step 1: Gather context**
41
+ ```
42
+ chorus_get_proposal({ proposalUuid: "<uuid>", section: "full" })
43
+ chorus_get_comments({ targetType: "proposal", targetUuid: "<uuid>" })
44
+ chorus_get_idea({ ideaUuid: "<idea-uuid>" })
45
+ chorus_get_elaboration({ ideaUuid: "<idea-uuid>" })
46
+ ```
47
+ > `chorus_get_proposal` defaults to `section: "basic"` (metadata + a lightweight draft index, no bodies). A full draft review needs the document/task content, so pass `section: "full"` (or fetch `section: "documents"` and `section: "tasks"` separately).
48
+
49
+ **Step 2: Review documents** — for each document draft, check:
50
+ - **Completeness**: Does the PRD cover functional, non-functional, error scenarios, and edge cases?
51
+ - **Specificity**: Are requirements testable? "Should handle errors gracefully" is not testable.
52
+ - **Tech feasibility**: Does the architecture make sense? Missing auth, race conditions, no error handling?
53
+ - **Module contracts**: If multiple tasks share interfaces, are return formats, error patterns, and call points defined?
54
+ - **Hallucination risk**: Flag any specific external detail that looks LLM-fabricated (API signatures, model IDs, SDK versions, CLI flags, config keys, endpoint paths) as NOTE. The PM is an LLM — it confidently invents plausible-looking specifics.
55
+
56
+ **Step 3: Review task drafts** — for each task draft, check:
57
+ - **Granularity**: Each task should be cohesive and independently testable. 2–10 AC items is the sweet spot.
58
+ - **AC quality**: Each criterion must be objectively verifiable by a different agent. "Shows details" is BAD. "Displays order ID, customer name, and status badge" is GOOD.
59
+ - **Coverage**: Cross-reference task AC against document requirements. Any requirement with NO corresponding AC?
60
+ - **Dependencies**: Is the DAG correct? Can each task start once its dependencies are done?
61
+ - **Integration checkpoints**: For DAGs with 4+ tasks, at least one task must be an integration checkpoint whose AC requires end-to-end execution of preceding modules together. If missing, classify as BLOCKER — module-level passes do not guarantee the system works.
62
+ - **Hallucination risk**: Task descriptions/AC may contain LLM-fabricated specifics. Flag as NOTE — same rule as Step 2.
63
+
64
+ **Step 4: Cross-check**
65
+ - Do tasks cover ALL requirements from the documents?
66
+ - Are there scope additions not in the original idea?
67
+ - Are there contradictions between documents and tasks?
68
+
69
+ ## Finding classification
70
+
71
+ **BLOCKER** — blocks implementation correctness: missing critical AC/NFR coverage; functional scope contradiction between documents; interface design flaw causing runtime errors; incorrect task dependencies.
72
+
73
+ **NOTE** — does not block: pseudocode signature mismatch (parameter order, naming); wording differences between PRD and tech design; style/naming suggestions; non-semantic document inconsistencies.
74
+
75
+ Rules: Pseudocode inconsistencies → always NOTE. Cross-document wording differences → always NOTE. Only semantic contradictions → BLOCKER. VERDICT: has BLOCKERs → FAIL; only NOTEs → PASS WITH NOTES; nothing → PASS.
76
+
77
+ ## Round awareness
78
+
79
+ - **Round 1**: full review, normal strictness.
80
+ - **Round 2+**: focus ONLY on whether previous BLOCKERs were fixed. Do NOT introduce new NOTEs on areas not flagged before. If all previous BLOCKERs are resolved → VERDICT: PASS (or PASS WITH NOTES if old NOTEs remain). Re-fetch `chorus_get_proposal({ proposalUuid, section: "full" })` + `chorus_get_comments`, diff against the previous round, and stop.
81
+
82
+ ## Recognize your own rationalizations
83
+
84
+ - "The proposal looks well-structured" — structure is not substance.
85
+ - "The PM probably considered this" — the PM is an LLM. Check it yourself.
86
+ - "There are enough tasks" — count is not coverage. Map requirements to tasks.
87
+
88
+ ## Output format (required)
89
+
90
+ ```
91
+ ### Review Summary
92
+
93
+ **PASS (N):** Check-1 name, Check-2 name, ...
94
+
95
+ **NOTE (M):**
96
+ - Note-1: [one-line description]
97
+
98
+ **BLOCKER (K):**
99
+ ### Blocker-1: name
100
+ **Evidence:** [specific finding]
101
+ **Expected:** [what should be there]
102
+ **Actual:** [what is there or what is missing]
103
+
104
+ VERDICT: PASS / PASS WITH NOTES / FAIL
105
+ ```
106
+
107
+ PASS items: names only. NOTE items: one-line. BLOCKER items: full evidence. Total under 800 chars. No preamble. The final line MUST start with `VERDICT:`.
108
+
109
+ ## Post results
110
+
111
+ Post the full review as a single comment, then you are done:
112
+ ```
113
+ chorus_add_comment({
114
+ targetType: "proposal",
115
+ targetUuid: "<proposal-uuid>",
116
+ content: "<your review>"
117
+ })
118
+ ```