feat(tasks): convert review-adversarial-general XML task to native skill (#1857)

* feat(tasks): convert review-adversarial-general from XML task to native skill

Convert the simplest core task (review-adversarial-general.xml) from
type:task XML format to type:skill markdown format. This establishes
the pattern for converting remaining XML tasks to self-contained skills.

- Convert XML task to workflow.md with frontmatter, role, execution steps
- Add type:skill manifest for verbatim directory copying
- Extend manifest-generator getTasksFromDir to recurse into subdirectories
  and detect type:skill entries (mirrors existing workflow skill detection)
- Update cross-references in quick-dev-new-preview, quick-dev, quick-spec
- Update module-help.csv to use skill: prefix

* refactor: replace file path references with skill name invocations

Consumers of review-adversarial-general now invoke by skill name
instead of loading via _bmad/ file path. Removes the indirection
variable from frontmatter and inlines the skill name directly.

* refactor(installer): scan tasks/ for type:skill entries

Teach collectWorkflows to also scan the tasks/ subdirectory for
type:skill entries. Skills can live anywhere in the source tree —
the workflow scanner just needs to look in more places.

* fix: update stale task terminology to skill after format conversion

Address review findings from PR #1857: replace remaining "task"
references with "skill" in workflow steps and test documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alex Verkhovsky 2026-03-08 06:52:55 -06:00 committed by GitHub
parent dc8293e5df
commit 835d6d85a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 66 additions and 90 deletions

View File

@ -2,7 +2,6 @@
name: 'step-04-review'
description: 'Adversarial review, classify findings, optional spec loop'
adversarial_review_task: '{project-root}/_bmad/core/tasks/review-adversarial-general.xml'
edge_case_hunter_task: '{project-root}/_bmad/core/tasks/review-edge-case-hunter.xml'
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
specLoopIteration: 1
@ -27,11 +26,11 @@ Do NOT `git add` anything — this is read-only inspection.
### Review
**One-shot:** Skip diff construction. Still invoke `{adversarial_review_task}` in a subagent with the changed files — inline review invites anchoring bias.
**One-shot:** Skip diff construction. Still invoke the `bmad-review-adversarial-general` skill in a subagent with the changed files — inline review invites anchoring bias.
**Plan-code-review:** Launch three subagents without conversation context. If no sub-agents are available, generate three review prompt files in `{implementation_artifacts}` — one per reviewer role below — and HALT. Ask the human to run each in a separate session (ideally a different LLM) and paste back the findings.
- **Blind hunter** — receives `{diff_output}` only. No spec, no context docs, no project access. Invoke via `{adversarial_review_task}`.
- **Blind hunter** — receives `{diff_output}` only. No spec, no context docs, no project access. Invoke via the `bmad-review-adversarial-general` skill.
- **Edge case hunter** — receives `{diff_output}` and read access to the project. Invoke via `{edge_case_hunter_task}`.
- **Acceptance auditor** — receives `{diff_output}`, `{spec_file}`, and read access to the project. Must also read the docs listed in `{spec_file}` frontmatter `context`. Checks for violations of acceptance criteria, rules, and principles from the spec and context docs.

View File

@ -6,9 +6,6 @@ main_config: '{project-root}/_bmad/bmm/config.yaml'
# Related workflows
advanced_elicitation: '{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.md'
party_mode_exec: '{project-root}/_bmad/core/workflows/party-mode/workflow.md'
# Review building block
adversarial_review_task: '{project-root}/_bmad/core/tasks/review-adversarial-general.xml'
---
# Quick Dev New Preview Workflow

View File

@ -1,13 +1,13 @@
---
name: 'step-05-adversarial-review'
description: 'Construct diff and invoke adversarial review task'
description: 'Construct diff and invoke adversarial review skill'
nextStepFile: './step-06-resolve-findings.md'
---
# Step 5: Adversarial Code Review
**Goal:** Construct diff of all changes, invoke adversarial review task, present findings.
**Goal:** Construct diff of all changes, invoke adversarial review skill, present findings.
---
@ -57,21 +57,15 @@ Merge all changes into `{diff_output}`.
### 2. Invoke Adversarial Review
With `{diff_output}` constructed, load and follow the review task. If possible, use information asymmetry: load this step, and only it, in a separate subagent or process with read access to the project, but no context except the `{diff_output}`.
With `{diff_output}` constructed, invoke the `bmad-review-adversarial-general` skill. If possible, use information asymmetry: invoke the skill in a separate subagent or process with read access to the project, but no context except the `{diff_output}`.
```xml
<invoke-task>Review {diff_output} using {project-root}/_bmad/core/tasks/review-adversarial-general.xml</invoke-task>
```
**Platform fallback:** If task invocation not available, load the task file and follow its instructions inline, passing `{diff_output}` as the content.
The task should: review `{diff_output}` and return a list of findings.
Pass `{diff_output}` as the content to review. The skill should return a list of findings.
---
### 3. Process Findings
Capture the findings from the task output.
Capture the findings from the skill output.
**If zero findings:** HALT - this is suspicious. Re-analyze or request user guidance.
Evaluate severity (Critical, High, Medium, Low) and validity (real, noise, undecided).
DO NOT exclude findings based on severity or validity unless explicitly asked to do so.
@ -91,7 +85,7 @@ With findings in hand, read fully and follow: `{project-root}/_bmad/bmm/workflow
- Diff constructed from baseline_commit
- New files included in diff
- Task invoked with diff as input
- Skill invoked with diff as input
- Findings received
- Findings processed into TODOs or table and presented to user
@ -99,6 +93,6 @@ With findings in hand, read fully and follow: `{project-root}/_bmad/bmm/workflow
- Missing baseline_commit (can't construct accurate diff)
- Not including new untracked files in diff
- Invoking task without providing diff input
- Invoking skill without providing diff input
- Accepting zero findings without questioning
- Presenting fewer findings than the review task returned without explicit instruction to do so
- Presenting fewer findings than the review skill returned without explicit instruction to do so

View File

@ -151,14 +151,12 @@ b) **HALT and wait for user selection.**
#### Adversarial Review [R] Process:
1. **Invoke Adversarial Review Task**:
> With `{finalFile}` constructed, load and follow the review task. If possible, use information asymmetry: load this task, and only it, in a separate subagent or process with read access to the project, but no context except the `{finalFile}`.
<invoke-task>Review {finalFile} using {project-root}/_bmad/core/tasks/review-adversarial-general.xml</invoke-task>
> **Platform fallback:** If task invocation not available, load the task file and follow its instructions inline, passing `{finalFile}` as the content.
> The task should: review `{finalFile}` and return a list of findings.
1. **Invoke Adversarial Review Skill**:
> With `{finalFile}` constructed, invoke the `bmad-review-adversarial-general` skill. If possible, use information asymmetry: invoke the skill in a separate subagent or process with read access to the project, but no context except the `{finalFile}`.
> Pass `{finalFile}` as the content to review. The skill should return a list of findings.
2. **Process Findings**:
> Capture the findings from the task output.
> Capture the findings from the skill output.
> **If zero findings:** HALT - this is suspicious. Re-analyze or request user guidance.
> Evaluate severity (Critical, High, Medium, Low) and validity (real, noise, undecided).
> DO NOT exclude findings based on severity or validity unless explicitly asked to do so.

View File

@ -6,5 +6,5 @@ core,anytime,Index Docs,ID,,_bmad/core/tasks/index-docs.xml,bmad-index-docs,fals
core,anytime,Shard Document,SD,,_bmad/core/tasks/shard-doc.xml,bmad-shard-doc,false,,,"Split large documents into smaller files by sections. Use when doc becomes too large (>500 lines) to manage effectively.",,
core,anytime,Editorial Review - Prose,EP,,_bmad/core/tasks/editorial-review-prose.xml,bmad-editorial-review-prose,false,,,"Review prose for clarity, tone, and communication issues. Use after drafting to polish written content.",report located with target document,"three-column markdown table with suggested fixes",
core,anytime,Editorial Review - Structure,ES,,_bmad/core/tasks/editorial-review-structure.xml,bmad-editorial-review-structure,false,,,"Propose cuts, reorganization, and simplification while preserving comprehension. Use when doc produced from multiple subprocesses or needs structural improvement.",report located with target document,
core,anytime,Adversarial Review (General),AR,,_bmad/core/tasks/review-adversarial-general.xml,bmad-review-adversarial-general,false,,,"Review content critically to find issues and weaknesses. Use for quality assurance or before finalizing deliverables. Code Review in other modules run this automatically, but its useful also for document reviews",,
core,anytime,Adversarial Review (General),AR,,skill:bmad-review-adversarial-general,bmad-review-adversarial-general,false,,,"Review content critically to find issues and weaknesses. Use for quality assurance or before finalizing deliverables. Code Review in other modules run this automatically, but its useful also for document reviews",,
core,anytime,Edge Case Hunter Review,ECH,,_bmad/core/tasks/review-edge-case-hunter.xml,bmad-review-edge-case-hunter,false,,,"Walk every branching path and boundary condition in code, report only unhandled edge cases. Use alongside adversarial review for orthogonal coverage - method-driven not attitude-driven.",,

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -0,0 +1 @@
type: skill

View File

@ -0,0 +1,37 @@
---
name: bmad-review-adversarial-general
description: 'Perform a Cynical Review and produce a findings report. Use when the user requests a critical review of something'
---
# Adversarial Review (General)
**Goal:** Cynically review content and produce findings.
**Your Role:** You are a cynical, jaded reviewer with zero patience for sloppy work. The content was submitted by a clueless weasel and you expect to find problems. Be skeptical of everything. Look for what's missing, not just what's wrong. Use a precise, professional tone — no profanity or personal attacks.
**Inputs:**
- **content** — Content to review: diff, spec, story, doc, or any artifact
- **also_consider** (optional) — Areas to keep in mind during review alongside normal adversarial analysis
## EXECUTION
### Step 1: Receive Content
- Load the content to review from provided input or context
- If content to review is empty, ask for clarification and abort
- Identify content type (diff, branch, uncommitted changes, document, etc.)
### Step 2: Adversarial Analysis
Review with extreme skepticism — assume problems exist. Find at least ten issues to fix or improve in the provided content.
### Step 3: Present Findings
Output findings as a Markdown list (descriptions only).
## HALT CONDITIONS
- HALT if zero findings — this is suspicious, re-analyze or ask for guidance
- HALT if content is empty or unreadable

View File

@ -18,11 +18,6 @@ index-docs.xml:
type: task
description: "Generates or updates an index.md to reference all docs in the folder"
review-adversarial-general.xml:
canonicalId: bmad-review-adversarial-general
type: task
description: "Perform a Cynical Review and produce a findings report"
review-edge-case-hunter.xml:
canonicalId: bmad-review-edge-case-hunter
type: task

View File

@ -1,49 +0,0 @@
<!-- if possible, run this in a separate subagent or process with read access to the project,
but no context except the content to review -->
<task id="_bmad/core/tasks/review-adversarial-general.xml" name="Adversarial Review (General)"
description="Perform a Cynical Review and produce a findings report. Use when the user requests a critical review of something">
<objective>Cynically review content and produce findings</objective>
<inputs>
<input name="content" desc="Content to review - diff, spec, story, doc, or any artifact" />
<input name="also_consider" required="false"
desc="Optional areas to keep in mind during review alongside normal adversarial analysis" />
</inputs>
<llm critical="true">
<i>MANDATORY: Execute ALL steps in the flow section IN EXACT ORDER</i>
<i>DO NOT skip steps or change the sequence</i>
<i>HALT immediately when halt-conditions are met</i>
<i>Each action xml tag within step xml tag is a REQUIRED action to complete that step</i>
<i>You are a cynical, jaded reviewer with zero patience for sloppy work</i>
<i>The content was submitted by a clueless weasel and you expect to find problems</i>
<i>Be skeptical of everything</i>
<i>Look for what's missing, not just what's wrong</i>
<i>Use a precise, professional tone - no profanity or personal attacks</i>
</llm>
<flow>
<step n="1" title="Receive Content">
<action>Load the content to review from provided input or context</action>
<action>If content to review is empty, ask for clarification and abort task</action>
<action>Identify content type (diff, branch, uncommitted changes, document, etc.)</action>
</step>
<step n="2" title="Adversarial Analysis" critical="true">
<mandate>Review with extreme skepticism - assume problems exist</mandate>
<action>Find at least ten issues to fix or improve in the provided content</action>
</step>
<step n="3" title="Present Findings">
<action>Output findings as a Markdown list (descriptions only)</action>
</step>
</flow>
<halt-conditions>
<condition>HALT if zero findings - this is suspicious, re-analyze or ask for guidance</condition>
<condition>HALT if content is empty or unreadable</condition>
</halt-conditions>
</task>

View File

@ -1,6 +1,6 @@
# Adversarial Review Test Suite
Tests for the `also_consider` optional input in `review-adversarial-general.xml`.
Tests for the `also_consider` optional input in the `bmad-review-adversarial-general` skill.
## Purpose
@ -19,12 +19,12 @@ All tests use `sample-content.md` - a deliberately imperfect User Authentication
## Running Tests
For each test case in `test-cases.yaml`, invoke the adversarial review task.
For each test case in `test-cases.yaml`, invoke the adversarial review skill.
### Manual Test Invocation
```
Review this content using the adversarial review task:
Review this content using the adversarial review skill:
<content>
[paste sample-content.md]

View File

@ -1,9 +1,9 @@
# Test Cases for review-adversarial-general.xml with also_consider input
# Test Cases for bmad-review-adversarial-general skill with also_consider input
#
# Purpose: Evaluate how the optional also_consider input influences review findings
# Content: All tests use sample-content.md (User Authentication API docs)
#
# To run: Manually invoke the task with each configuration and compare outputs
# To run: Manually invoke the skill with each configuration and compare outputs
test_cases:
# BASELINE - No also_consider

View File

@ -156,6 +156,10 @@ class ManifestGenerator {
if (await fs.pathExists(modulePath)) {
const moduleWorkflows = await this.getWorkflowsFromPath(modulePath, moduleName);
this.workflows.push(...moduleWorkflows);
// Also scan tasks/ for type:skill entries (skills can live anywhere)
const tasksSkills = await this.getWorkflowsFromPath(modulePath, moduleName, 'tasks');
this.workflows.push(...tasksSkills);
}
}
}
@ -163,9 +167,9 @@ class ManifestGenerator {
/**
* Recursively find and parse workflow.yaml and workflow.md files
*/
async getWorkflowsFromPath(basePath, moduleName) {
async getWorkflowsFromPath(basePath, moduleName, subDir = 'workflows') {
const workflows = [];
const workflowsPath = path.join(basePath, 'workflows');
const workflowsPath = path.join(basePath, subDir);
const debug = process.env.BMAD_DEBUG_MANIFEST === 'true';
if (debug) {
@ -246,8 +250,8 @@ class ManifestGenerator {
// Build relative path for installation
const installPath =
moduleName === 'core'
? `${this.bmadFolderName}/core/workflows/${relativePath}/${entry.name}`
: `${this.bmadFolderName}/${moduleName}/workflows/${relativePath}/${entry.name}`;
? `${this.bmadFolderName}/core/${subDir}/${relativePath}/${entry.name}`
: `${this.bmadFolderName}/${moduleName}/${subDir}/${relativePath}/${entry.name}`;
// Check if this is a type:skill entry — collect separately, skip workflow CSV
const artifactType = this.getArtifactType(skillManifest, entry.name);