
Expert
- 1 installs
- 2 repo stars
- Updated July 2, 2026
- doctormozg/claude-pipelines
Orchestrates a Delphi-style 5-lens expert panel that critiques an idea over three rounds and writes a multi-sided analysis report.
About
Orchestrates a Delphi-style expert panel that critiques an idea across multiple lenses over three rounds, producing a multi-sided analysis report. A developer uses it for multi-angle critique of a proposal.
- Runs a Delphi-style panel of 5 lenses over 3 fixed rounds
- Produces a multi-sided analysis report critiquing an idea
Expert by the numbers
- 1 all-time installs (skills.sh)
- Ranked #2,479 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Jul 8, 2026 (Skillselion catalog sync)
npx skills add https://github.com/doctormozg/claude-pipelines --skill expertAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 2, 2026 |
| Repository | doctormozg/claude-pipelines ↗ |
What it does
Orchestrates a Delphi-style 5-lens expert panel that critiques an idea over three rounds and writes a multi-sided analysis report.
Files
Expert Consultation Pipeline
Overview
You orchestrate a Delphi-style expert panel review. A curated panel of 5 lenses — selected from 16 available perspectives — critiques an idea over 3 fixed rounds. Each round every panelist emits a structured 5-field view (strengths/weaknesses/risks/suggestions/confidence); a neutral round synthesizer consolidates the outputs; the next round's panelists receive the summary plus their own prior view and may alter their position. After round 3, a dedicated report writer produces a multi-sided analysis report.
When to Use
Invoke when the user wants a critical, multi-lens analysis of a specific proposal, plan, architecture, business idea, or design decision. Trigger phrases: "expert review of", "critique this idea", "strengths and weaknesses of", "multi-angle analysis", "consult experts on".
When NOT to use
- The user wants to generate ideas from scratch — use
brainstorm. - The user wants a single concrete decision or implementation — use
build. - The user wants verification of an existing codebase change — use
auditorreview-branch. - The problem has one objectively correct answer knowable from docs — look it up instead of consulting a panel.
Input
$ARGUMENTS — The idea, proposal, or plan to review. Supports inline modifiers:
scope:branch|global|working— when set,expert-researcherscans the codebase first so experts can ground feedback in real code (default: pure idea analysis, no scan)@doc:<path>— existing requirement/brief/RFC document to ingest
If $ARGUMENTS is empty, ask the user via AskUserQuestion. Never guess.
Constants
- PANEL_SIZE: 5
- TOTAL_LENSES: 16
- ROUNDS: 3 (fixed — no early stopping, no convergence check)
- TASK_DIR:
.mz/task/ - REPORT_DIR:
.mz/reports/
Available Lenses
Panel picks 5 from 16 lenses: lens-engineer, lens-artist, lens-philosopher, lens-mathematician, lens-scientist, lens-economist, lens-storyteller, lens-futurist, lens-psychologist, lens-historian, lens-cto, lens-seo, lens-security, lens-product, lens-devops, lens-data. Use the brief to balance primary, adjacent, and productive-tension lenses. Behavior is injected by this skill (critique mode); the same lens agents serve /brainstorm in ideation mode.
Core Process
Phase Overview
| # | Phase | File | Loop? |
|---|---|---|---|
| 0 | Setup | inline below | — |
| 1 | Intake + Optional Research + Panel | phases/intake_and_panel.md | — |
| 1.5 | Panel Approval Gate | Inline below (+ phases/intake_and_panel.md for details) | user-feedback sub-loop |
| 2 | Round Loop | phases/round_loop.md | fixed 3 rounds, no early-out |
| 3 | Final Report | phases/final_report.md | — |
Phase 0: Setup
1. Parse $ARGUMENTS. Extract brief, scope:, @doc: refs. 1. If brief is empty → AskUserQuestion. Never guess. 1. task_name = <YYYY_MM_DD>_expert_<slug> where <YYYY_MM_DD> is today's date (underscores) and slug is a snake_case summary (max 20 chars); on same-day collision append _v2, _v3. 1. Create .mz/task/<task_name>/. 1. Write state.md with schema_version: 2, Status, Phase, Started, phase_complete: false, what_remains: [], Round: 0, FilesWritten: []. 1. Emit a visible setup block: task_name, working dir, report dir, detected modifiers.
Phase 1.5: Panel Approval Gate
This orchestrator (not a subagent) presents this gate. This step is interactive and must not be delegated.
Pre-read: Read .mz/task/<task_name>/panel.md and capture the full contents (5 selected panelist lenses with one-line rationale per pick — primary, adjacent, productive-tension picks all justified) into context. See phases/intake_and_panel.md Step 1.4 for the panel.md content schema.
Surface 1 — emit the plan message. Output the full verbatim contents of .mz/task/<task_name>/panel.md as a normal markdown chat message. Emit the full verbatim contents — do not substitute a path, summary, or placeholder. Structure:
## Panel ready for review — expert
<verbatim contents of .mz/task/<task_name>/panel.md>
---
**Approve** → begin 3 rounds of expert critique · **Reject** → cancel task, no rounds will run · reply with feedback to reviseSurface 2 — call AskUserQuestion. After the plan message, call AskUserQuestion. The question must NOT re-embed the panel — it lives in the plan message above.
- question:
The panel above is ready for review. - options: Approve — begin 3 rounds of expert critique · Reject — cancel task, no rounds will run
Response handling:
- Approve → update
state.mdtopanel_approved, proceed to Phase 2 (Round Loop). - Reject → update
state.mdtoaborted_by_userand stop. Do not run rounds. - Any other reply (feedback) → apply swaps/changes, overwrite
panel.md, return to Surface 1, re-readpanel.md, and re-emit the entire plan message from scratch with the full new contents — never diff-only, never summary-only, since context compaction may have destroyed the user's memory of earlier iterations. This is a loop — repeat until the user explicitly approves. Never proceed to Phase 2 without explicit approval.
Techniques
Techniques: delegated to phase files — see Phase Overview table above.
Common Rationalizations
N/A — collaboration/reference skill, not a discipline skill.
Red Flags
- You skipped the panel-approval gate.
- You exited the round loop before 3 rounds completed.
- You serialized the 5 panelists instead of dispatching in one parallel message per round.
- You let a panelist write
round_<N>_summary.mdinstead of dispatchingexpert-round-synthesizer. - You wrote the final report inline instead of dispatching
expert-report-writer. - The final report has claims not attributed to a specific panelist + round.
Verification
At the end of Phase 3, output a visible block:
Expert consultation finalized.
Task dir: .mz/task/<task_name>/
Report: .mz/reports/<YYYY_MM_DD>_expert_<slug>.md
Panel: <5 agent names>
Rounds: 3/3
Files:
- intake.md
- research.md (if scope: set)
- panel.md
- iter_1_<agent>.md × 5, round_1_summary.md
- iter_2_<agent>.md × 5, round_2_summary.md
- iter_3_<agent>.md × 5, round_3_summary.md
- final report at .mz/reports/If any phase is incomplete, print the blocker explicitly. The verification block is mandatory.
Error Handling
- Empty brief →
AskUserQuestion; never guess. @doc:path does not exist → ask the user whether to proceed without it.- Agent returns malformed output → retry once with clarified prompt; if still malformed, note the gap in state.md and continue (do not block the round on a single agent).
- Researcher fails when
scope:set → escalate to user; offer to proceed without scan. - Panel-approval gate rejected → mark state
aborted_by_user; stop without writing a report. - Update
state.mdbefore and after every agent dispatch.
State Management
After each phase, update .mz/task/<task_name>/state.md:
Status:pending|running|complete|aborted_by_user|failedPhase:0|1|1.5|2|3Round:0..3(Phase 2 only)FilesWritten:cumulative list
State persists to .mz/task/<task_name>/state.md. Schema is v2: the file's first line is schema_version: 2, and alongside the skill's existing Status / Phase / Started keys it carries phase_complete (boolean) and what_remains (YAML list of strings). Set phase_complete: false on phase entry and true once the phase's artifacts are written and its gates pass; refresh what_remains on every phase transition; what_remains MUST be [] when Status: complete. On reading a schema_version: 1 or unversioned file, add the missing keys, set schema_version: 2, and log the upgrade.
Never rely on conversation memory for cross-phase state — context compaction destroys specific paths and decisions. The state file is the source of truth.
Behavior: Critique
Dispatch contract for /expert lens panelists. The expert orchestrator reads this file, substitutes {variables}, and sends the composed prompt verbatim as the user message to each dispatched lens agent. Do not include this explanation or the outer code fence in the final prompt — only the text inside.
Template variables
| Variable | Source | Example |
|---|---|---|
{brief} | intake.md contents | — |
{research_block} | research.md contents if present, else literal text no codebase research run | — |
{round_n} | current round (1, 2, or 3) | 2 |
{prior_summary_block} | empty for R1; ## Previous round summary\n\n<round_{n-1}_summary.md> for R2/R3 | — |
{prior_iter_block} | empty for R1; ## Your prior output\n\n<iter_{n-1}_{agent_name}.md> for R2/R3 | — |
{output_path} | absolute path where the agent writes its artifact | .mz/task/xxx/iter_2_lens-engineer.md |
{lens_name} | short lens label, no prefix | engineer |
{agent_name} | full agent name | lens-engineer |
When R1, substitute empty strings for {prior_summary_block} and {prior_iter_block} and collapse the surrounding blank lines.
Dispatch prompt body
MODE: critique
OUTPUT: {output_path}
ROUND: {round_n}
## Brief
{brief}
## Research context
{research_block}
{prior_summary_block}
{prior_iter_block}
## How to work
### If ROUND is 1
1. Read the brief and research context.
2. From your lens, produce:
- 3–5 **strengths** your lens uniquely surfaces
- 3–5 **weaknesses** your lens uniquely surfaces
- 2–4 **risks** — failure modes, downstream costs, adversarial scenarios
- 2–5 **suggestions** — concrete, actionable, from your lens
3. Score the four rubric dimensions (see Scoring rubric below), each an integer 1–5 with a one-clause reason.
4. Set Confidence: High | Medium | Low, with one sentence on why.
### If ROUND is 2 or 3
1. Read the prior_summary_block — previous round's neutral synthesis of all 5 panelists.
2. Read the prior_iter_block — your own prior critique from round {round_n} minus 1.
3. React to peers by name when they surfaced something your lens should update on. Hold when your reasoning still applies — principled stagnation is fine.
4. Produce the same four sections (strengths, weaknesses, risks, suggestions) revised in light of the new information.
5. Re-score the four rubric dimensions. A score may hold or move; if it moves, the Changelog must say why.
6. Add a Reactions section: for each peer claim that mattered to you, one sentence referencing the peer by their lens name (e.g., `lens-cto raised cold-start costs I had not considered...`).
7. Add a Changelog: what moved from your prior round and why, or the literal text `no change: <principled reason>`.
8. Update Confidence.
## Critique rules
- Tie every concern to an observable mechanism; quantify where possible.
- Stay in your lens. Reference peers only in Reactions (R2/R3).
- If the brief is thin, downgrade Confidence; do not invent details.
- Every rubric score needs a one-clause reason tied to your critique sections — an unreasoned number is not a score.
## Scoring rubric
After the four critique sections, score the subject of the brief on four dimensions. Each is an integer 1–5. There is no weighting and no composite total — the four scores stand on their own.
- **Merit** — strength of the idea or code on its own terms. 5 = exceptional; 1 = fundamentally weak.
- **Feasibility** — how realistic delivery is given the brief's stated constraints. 5 = clearly deliverable; 1 = not deliverable as framed.
- **Risk exposure** — *higher is safer.* 5 = low risk, failure modes contained; 1 = high risk, severe or likely failure modes.
- **Readiness to proceed** — whether it can move forward now. 5 = proceed as-is; 1 = needs substantial rework first.
Score from your lens — an `engineer` and a `psychologist` will rate the same idea differently, and that spread is the signal. Do not converge toward a middle value to seem balanced. Scores are distinct from Confidence: the rubric rates the subject, Confidence rates how sure you are of your own read.
## Output schema
Write the following markdown to the file at OUTPUT.
### When ROUND is 1
# Lens: {lens_name} — critique round 1
## Strengths
- ...
## Weaknesses
- ...
## Risks
- ...
## Suggestions
- ...
## Scores
- Merit: <1-5>/5 — <one-clause reason>
- Feasibility: <1-5>/5 — <one-clause reason>
- Risk exposure: <1-5>/5 — <one-clause reason>
- Readiness to proceed: <1-5>/5 — <one-clause reason>
## Confidence
High | Medium | Low — one sentence why.
### When ROUND is 2 or 3
# Lens: {lens_name} — critique round {round_n}
## Strengths
- ...
## Weaknesses
- ...
## Risks
- ...
## Suggestions
- ...
## Scores
- Merit: <1-5>/5 — <one-clause reason>
- Feasibility: <1-5>/5 — <one-clause reason>
- Risk exposure: <1-5>/5 — <one-clause reason>
- Readiness to proceed: <1-5>/5 — <one-clause reason>
## Confidence
High | Medium | Low — one sentence why.
## Reactions
- lens-<peer>: <your reaction referencing their claim by name>
## Changelog
- <what changed from your prior round and why — or "no change: <principled reason>">
## Terminal status line
End your response with exactly one of:
- `STATUS: DONE` — output written, on-lens, all sections present.
- `STATUS: DONE_WITH_CONCERNS` — wrote the file but flagged caveats above this line.
- `STATUS: NEEDS_CONTEXT` — cannot proceed; name the missing input above this line.
- `STATUS: BLOCKED` — unresolvable state.Orchestrator post-dispatch checklist
1. Verify the file at {output_path} was created. 1. Validate structure: Strengths/Weaknesses/Risks/Suggestions/Scores/Confidence present (R1); plus Reactions/Changelog (R2/R3). 1. Validate terminal STATUS: line in the agent's response — parse it and log. 1. On malformed / empty / wrong STATUS: retry once with a clarified prompt; if still bad, note the gap in state.md and downgrade the synthesizer's confidence rating for that agent in that round.
Phase 3: Final Report
Full detail for dispatching expert-report-writer and producing the polished report. No user approval gate at this phase — the report is written, its path is returned, and the skill exits.
Goal
Produce a single structured report at .mz/reports/<YYYY_MM_DD>_expert_<slug>.md synthesising the 3 rounds into a multi-sided analysis.
Inputs
From Phase 2:
panel.mdintake.md(+research.mdifscope:was set)iter_1_<agent>.md× 5,round_1_summary.mditer_2_<agent>.md× 5,round_2_summary.mditer_3_<agent>.md× 5,round_3_summary.md
Step 3.1 — Pre-dispatch checks
Verify all artifacts are on disk. If any round file is missing, log the gap and proceed anyway — the report writer must document gaps rather than block.
ls .mz/task/<task_name>/iter_{1,2,3}_*.md .mz/task/<task_name>/round_{1,2,3}_summary.mdStep 3.2 — Compute report filename
Slug = same as task_name slug portion. Date = today's date in YYYY_MM_DD.
report_path = .mz/reports/<YYYY_MM_DD>_expert_<slug>.mdIf the file already exists, append _v2, _v3, … until a free slot is found. Ensure .mz/reports/ exists (mkdir -p) before dispatch.
Step 3.3 — Dispatch expert-report-writer
Spawn expert-report-writer (model: sonnet) with this prompt:
You are producing the final report for an expert panel review.
## Task Directory
.mz/task/<task_name>/
## Output path
<computed report_path from step 3.2>
## Read
- .mz/task/<task_name>/intake.md
- .mz/task/<task_name>/research.md (if exists)
- .mz/task/<task_name>/panel.md
- .mz/task/<task_name>/iter_1_<each panelist>.md (5 files)
- .mz/task/<task_name>/round_1_summary.md
- .mz/task/<task_name>/iter_2_<each panelist>.md (5 files)
- .mz/task/<task_name>/round_2_summary.md
- .mz/task/<task_name>/iter_3_<each panelist>.md (5 files)
- .mz/task/<task_name>/round_3_summary.md
## Your Job
Write the final report to the output path following the schema in your agent spec. Key rules:
1. Every claim in the report must be attributable to a specific agent + round. Use inline tags like "[lens-cto R2]" so the reader can trace.
2. The Executive Summary must be 3-5 sentences. It is the only thing most readers will read. Make it land.
3. Consensus Findings capture what held across all 3 rounds — NOT what appeared once. Cite round numbers.
4. Divergent Views must present BOTH sides with the agents on each side and the core tradeoff. Never resolve the tension — let the reader decide.
5. Recommendations are ranked by panel endorsement strength. Each recommendation lists the agents who endorsed it (not just the round-3 view — weigh consistency across rounds).
6. Per-Expert Takes come verbatim from round 3 (last position). Do not rewrite — quote or paraphrase tightly.
7. Methodology block must list: panel composition, rounds run, synthesizer, source files (relative paths), and the task directory.
## Rules
- No generic filler. Every section earns its place.
- No chart or diagram (it's a markdown report, not a deck).
- If a gap was logged in state.md (missing panelist output in a round), note it in Methodology → Gaps.
- Do not invent agent names. Only the 5 panelists listed in panel.md.
- Do not exceed ~600 lines. A tight report beats a long one.
Terminal status line: STATUS: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKEDStep 3.4 — Handle writer status
DONE— verify the file exists and is non-empty; proceed to Step 3.5.DONE_WITH_CONCERNS— log concerns; verify file; proceed.NEEDS_CONTEXT— re-dispatch with the missing piece (most commonly a missing file path or ambiguous panel entry).BLOCKED— escalate to user viaAskUserQuestion. Offer: accept partial report (inspect what was written), re-run report writer with guidance, abort without a report.
Step 3.5 — Verify report
test -s <report_path>Structural sanity:
grep -c '^## ' <report_path>Should be ≥ 8 (Executive Summary, Consensus Findings, Divergent Views, Strengths, Weaknesses, Top Risks, Recommendations, Per-Expert Takes, Methodology). If fewer, dispatch a revision pass with the missing sections listed.
Step 3.6 — Update state to complete
schema_version: 2
Status: complete
Phase: 3
PhaseName: report_written
phase_complete: true
what_remains: []
Round: 3
Completed: <timestamp>
ReportPath: <report_path>
FilesWritten:
- ... (append report_path)Step 3.7 — Emit final completion block
Output a visible block to the user:
Expert consultation finalized.
Task dir: .mz/task/<task_name>/
Report: <report_path>
Panel: <5 names>
Rounds: 3/3
Top-line findings (from Executive Summary):
<first 3 bullets or sentences from the report's Executive Summary>Do not print the full report inline — it is on disk, and the user knows where to find it.
Notes
- There is no user approval gate at Phase 3 by design (confirmed with user). The panel was already gated at Phase 1.5. A second gate would add friction without new information.
- If the user wants iterative feedback on the report, they can re-run
/expertwith a narrower follow-up brief that references the prior report. - The report writer is sonnet (not opus) because synthesis benefits from breadth-over-depth and sonnet handles long-context reliably at lower cost.
.mz/reports/is the same directory brainstorm uses. Naming convention<date>_expert_<slug>.mdavoids collision with<date>_brainstorm_<slug>.mdvia the type segment.
Phase 1: Intake + Optional Research + Panel Selection
Full detail for intake, the optional codebase scan (when scope: is set), panel selection, and the approval gate.
Goal
Produce intake.md, optionally research.md, and a user-approved panel.md listing the 5 selected experts. No expert is dispatched for critique until the panel is explicitly approved.
Inputs
From Phase 0:
- Brief text
- Optional modifiers:
scope:branch|global|working,@doc:<path> - Task name and working directory
Step 1.1 — Write intake.md
This orchestrator writes intake.md directly. Do not delegate intake authoring — the orchestrator already has the brief in its context.
Template:
# Intake
## Brief
<verbatim brief text>
## Modifiers
- scope: <branch|global|working|none>
- doc refs: <list of @doc: paths, or "none">
## Doc summaries (if @doc: refs present)
### <path>
<2-3 sentence summary of the doc contents — orchestrator reads each referenced file and summarises>
## Detected framing
- Problem type: <technical | product | business | design | strategic | mixed>
- Decision scope: <architecture | feature | platform | process | branding | policy | other>
- Urgency signal: <none | implied | explicit>The "Detected framing" section biases panel selection. Be specific but brief.
Step 1.2 — Optional codebase scan (when scope: is set)
If the user provided scope:, dispatch expert-researcher (model: sonnet) with this prompt:
You are researching codebase context for an expert panel review.
## Brief
<verbatim brief>
## Scope
<branch|global|working>
## Task Directory
.mz/task/<task_name>/
## Your Job
Scan the codebase within the declared scope and write research.md. Capture:
1. Stack detection (languages, frameworks, major libraries) — emit STACK DETECTED: lines
2. Relevant modules/directories that the brief's idea would touch
3. Existing patterns, conventions, naming, test infrastructure
4. Prior art: has anything similar been attempted in the repo? Any dead branches, old spike code, relevant commits?
5. Constraints visible from code: version pinning, protocol assumptions, public interfaces that must remain stable
Emit disclosure tokens where applicable:
- STACK DETECTED: <stack + version>
- CONFLICT DETECTED: <when codebase contradicts the brief's assumptions>
- UNVERIFIED: <when a claim cannot be grounded in code>
Focus on what an expert panel would need to critique the idea realistically — not an implementation plan. Do NOT propose solutions.
Terminal status line: STATUS: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED1.2.1 Handle researcher status
DONE— proceed to panel selection.DONE_WITH_CONCERNS— log concerns tostate.mdand proceed.NEEDS_CONTEXT— escalate specific question viaAskUserQuestion, then re-dispatch with added context.BLOCKED— escalate immediately. Offer: clarify the brief, proceed without scan (downgrade to pure idea analysis), abort.
1.2.2 Verify research.md
test -s .mz/task/<task_name>/research.mdIf missing or empty, retry once with explicit instruction. If still missing, escalate.
Step 1.3 — Panel selection
This orchestrator (not a subagent) selects the panel. The orchestrator already has the brief + research in context, so delegating panel selection would just burn tokens.
Selection heuristic
From the 16-lens pool, pick 5 lenses that:
1. Cover the primary lens the brief demands (e.g., a tech idea must include lens-cto or lens-engineer; an SEO/content idea must include lens-seo). 1. Cover 1–2 adjacent lenses (e.g., a tech idea should also include lens-security or lens-product for adjacent risk). 1. Include at least one "productive tension" lens — a perspective that will likely challenge the dominant view. For a tech idea, add lens-philosopher (ethics) or lens-historian (precedent). For a business idea, add lens-scientist (evidence) or lens-data (measurement). 1. Mix styles — include at least one generative/creative-family lens (e.g. lens-artist, lens-storyteller, lens-futurist) alongside operational lenses. A balanced panel surfaces more failure modes than an all-operational or all-creative panel. 1. Never duplicate a lens — e.g., don't pick both lens-engineer and lens-cto on the same panel; their lenses overlap too much.
Write panel.md
# Panel
## Topic
<the brief, one paragraph>
## Selected (5)
### <agent 1 name>
- **Lens**: <one-line lens from the SKILL.md roster>
- **Why this panel**: <one sentence explaining why this lens matters for the brief>
[repeat for all 5]
## Not selected (11)
<comma-separated list of the 11 agents not picked, no justification needed>
## Selection rationale
<2-3 sentences on overall panel balance — what tension was introduced, which lens is dominant, which lens is adversarial>Update state: Phase: 1, PhaseName: panel_selected.
Step 1.4 — User approval gate (Phase 1.5)
This orchestrator (not a subagent) presents this gate. This step is interactive and must not be delegated.
Pre-read: Read .mz/task/<task_name>/panel.md and capture the full contents into context.
Surface 1 — emit the plan message. Output the full verbatim contents of .mz/task/<task_name>/panel.md as a normal markdown chat message. Emit the full verbatim contents — do not substitute a path, summary, or placeholder. Structure:
## Panel ready for review — expert
<verbatim contents of .mz/task/<task_name>/panel.md>
---
**Approve** → begin 3 rounds of expert critique · **Reject** → cancel task, no rounds will run · reply with feedback to reviseSurface 2 — call AskUserQuestion. After the plan message, call AskUserQuestion. The question must NOT re-embed the panel — it lives in the plan message above.
- question:
The panel above is ready for review. - options: Approve — begin 3 rounds of expert critique · Reject — cancel task, no rounds will run
Response handling
- Approve → update state to
panel_approved, proceed to Phase 2. - Reject → update state to
aborted_by_user. Stop. Do not run rounds. - Any other reply (feedback) → apply the swap to
panel.md, return to Surface 1, re-readpanel.md, and re-emit the entire plan message from scratch with the full new contents. This is a loop — repeat until the user explicitly approves. Never proceed to Phase 2 without explicit approval.
Swap rules
- The user can swap up to all 5 members; the orchestrator may push back in the presentation block if a swap breaks the "at least 1 from each class" rule, but must still honor an explicit user choice.
- If the user removes the only technical lens from a technical brief, warn in the next presentation block but obey the user.
Step 1.5 — Verify and hand off
Before leaving Phase 1, verify:
intake.mdexists and is non-emptyresearch.mdexists (ifscope:was set)panel.mdexists and lists exactly 5 selected agentsstate.mdshowsStatus: running,Phase: 1.5,PhaseName: panel_approved
Proceed to Phase 2 (Round Loop).
Notes
- Phase 1 is not gated against the user before panel-selection (the researcher is read-only). The gate sits at Phase 1.5.
- Image references (
@image:) are intentionally unsupported —/expertis text-only by design. If the user provides one, note in intake.md and continue. - Panel selection is orchestrator-owned on purpose: delegating it to an agent would require loading the brief + research into a second context and re-reading the agent roster. Inline selection saves 1 agent call per run.
Phase 2: Round Loop
Full detail for the 3-round consultation loop. Each round is a parallel panelist dispatch followed by a round synthesizer. No early stopping, no convergence check — always 3 rounds.
Goal
Run the 5-member approved panel through 3 structured rounds of critique. Each round produces:
- 5 panelist outputs (
iter_<N>_<agent>.md) - 1 neutral synthesis (
round_<N>_summary.md)
Constants (from SKILL.md)
ROUNDS: 3 (fixed)PANEL_SIZE: 5
Loop structure
for N in 1..3:
2.1 Build per-agent context packet (varies by round — see below)
2.2 Dispatch all 5 panelists in ONE message (5 parallel Agent calls)
2.3 Collect iter_<N>_<agent>.md artifacts; retry any malformed once
2.4 Dispatch expert-round-synthesizer → round_<N>_summary.md
2.5 Verify summary; update state.md (Round: N)Step 2.1 — Build context packet from the critique behavior
Load plugins/mz-creative/skills/expert/behaviors/critique.md. That file defines the dispatch prompt template with {variable} placeholders inside a fenced text code block. That block is the entire message to send to each lens agent — nothing before it, nothing after it. You must substitute variables per-agent and per-round before dispatching.
Per-agent variable substitution
For each of the 5 selected lens agents, substitute:
| Variable | Value |
|---|---|
{brief} | verbatim contents of intake.md |
{research_block} | contents of research.md if present, else literal text no codebase research run |
{round_n} | current round number (1, 2, or 3) |
{prior_summary_block} | empty for R1; ## Previous round summary\n\n<verbatim round_<N-1>_summary.md> for R2/R3 |
{prior_iter_block} | empty for R1; ## Your prior output\n\n<verbatim iter_<N-1>_<agent_name>.md> for R2/R3 |
{output_path} | .mz/task/<task_name>/iter_<N>_<agent_name>.md |
{lens_name} | short lens label derived from the agent name (e.g. engineer for lens-engineer) |
{agent_name} | the full agent name (e.g. lens-engineer) |
When R1, substitute empty strings for {prior_summary_block} and {prior_iter_block} and collapse the surrounding blank lines so there is no stray empty section.
Step 2.2 — Parallel panelist dispatch
Read .mz/task/<task_name>/panel.md to get the 5 agent names. Before dispatching, emit a pre-dispatch manifest — wave label, a one-line purpose, and one bullet per panelist with its lens role — so the wave is visible to the user. See SKILL_GUIDELINES.md (Fan-Out Wave Observability).
Dispatch all 5 in one message (single tool-use block with 5 Agent calls). Each gets its own substituted dispatch prompt as the user message.
The 5 panelists are opus-class lens agents registered by their name: field (e.g., lens-engineer, lens-cto). Do not repeat agent system-prompt instructions — the critique behavior prompt is self-contained.
Parallelism is load-bearing. Sequential dispatch triples latency and introduces ordering bias. Never serialize.
Step 2.3 — Collect artifacts
For each panelist, verify:
test -s .mz/task/<task_name>/iter_<N>_<agent>.mdAnd that the file contains the required sections for the round. Quick check:
grep -c '^## Strengths\|^## Weaknesses\|^## Risks\|^## Suggestions\|^## Scores\|^## Confidence' \
.mz/task/<task_name>/iter_<N>_<agent>.mdShould return ≥ 6 for round 1 and ≥ 8 for rounds 2-3 (adds Reactions + Changelog).
Confirm the four rubric scores are present and well-formed:
grep -cE '^- (Merit|Feasibility|Risk exposure|Readiness to proceed): [1-5]/5' \
.mz/task/<task_name>/iter_<N>_<agent>.mdShould return 4. A file that passes the section-count check but returns fewer than 4 here has a malformed Scores block — treat it as malformed and retry per below.
If an agent output is missing or malformed
- Retry once with a clarified dispatch that explicitly lists the missing sections.
- If the retry still fails, log the gap in
state.mdunder a## Gapssection and continue the round without that agent's output. Never block a round on a single missing agent.
Once collection is settled, emit a post-wave rollup — a <returned>/<dispatched> count and one bullet per panelist with its status and a short summary — before dispatching the synthesizer. A panelist with no usable artifact shows as <agent>: NO RETURN BLOCK, never dropped from the count.
Step 2.4 — Dispatch round synthesizer
Once all 5 (or however many succeeded) panelist outputs are on disk, dispatch expert-round-synthesizer (model: sonnet):
You are the round synthesizer for an expert panel review. Your job is a neutral, lens-agnostic consolidation. You do not advocate.
## Task Directory
.mz/task/<task_name>/
## Round
<N>
## Read
- .mz/task/<task_name>/iter_<N>_<agent1>.md
- .mz/task/<task_name>/iter_<N>_<agent2>.md
- ... (all 5 panelist files for round <N>)
- .mz/task/<task_name>/panel.md
## Your Job
Write .mz/task/<task_name>/round_<N>_summary.md using the schema from your agent spec. Capture:
1. **Consensus** — points ≥3 of the 5 agents converged on. Quote or paraphrase specific agents.
2. **Divergence** — explicit conflicts. Name both sides. Capture the core tradeoff.
3. **Key tensions** — 2-3 unresolved tradeoffs the panel is circling.
4. **Emerging recommendations** — actions gaining traction across lenses. Tag which agents endorse each.
5. **Gaps** — important angles no panelist addressed.
6. **Score spread** — for each of the four rubric dimensions (Merit, Feasibility, Risk exposure, Readiness to proceed), report the range across the 5 lenses and name the high and low lens. Do not average — the spread is the signal.
## Rules
- Neutral tone. Do not weight any lens.
- Cite agents by name. Never say "the panel thinks" — say "<agent1>, <agent2>, and <agent3> converge on X".
- Do not add your own opinion.
- Be concise. This summary will be read by every agent in the next round; every extra token multiplies.
Terminal status line: STATUS: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKEDHandle synthesizer status
DONE— proceed to state update.DONE_WITH_CONCERNS— log concerns, proceed.NEEDS_CONTEXT— re-dispatch with the missing piece (usually pointing at a file); do not advance round counter.BLOCKED— escalate to user.
Step 2.5 — Update state
After each round, update state.md:
schema_version: 2
Status: running
Phase: 2
PhaseName: round_<N>_complete
phase_complete: <true once N == 3, else false>
what_remains:
- ... (rounds after <N> not yet run, then the Phase 3 final report)
Round: <N>
FilesWritten:
- ... (append iter_<N>_<agent>.md × 5 and round_<N>_summary.md)Emit a visible round-complete block to the user so they see progress:
Round <N>/3 complete.
Panelists responded: <count>/5
Summary: round_<N>_summary.md
Consensus points: <count>
Divergence points: <count>
Gaps: <count>Exit condition
After round 3 completes and round_3_summary.md is verified, proceed to Phase 3 (Final Report).
Do not exit early. The 3-round count is load-bearing: round 1 surfaces first impressions, round 2 lets the panel react to each other, round 3 gives each panelist a chance to hold or change their final position before the report is written. Cutting short drops the Delphi property.
Sub-agent status handling (four-status protocol)
Applies to the synthesizer (and researcher in Phase 1). Does not apply to panelist agents — panelists do not emit STATUS lines; they emit their structured markdown output and the orchestrator validates the sections.
DONE— proceed.DONE_WITH_CONCERNS— log and proceed.NEEDS_CONTEXT— add context, re-dispatch, do not advance.BLOCKED— escalate, never auto-retry.
Notes
- The synthesizer is lens-neutral on purpose. Rotating synthesizers (brainstorm's pattern) bias the inter-round context and pull the panel toward whichever lens synthesized.
- Round 3 receives only
round_2_summary.md, not round 1 summary. The panelist's own prior files carry their self-history. This prevents context bloat. - If a panelist's round 2 Changelog is empty across all 5 panelists, the panel has saturated — but that is NOT an early-exit signal. Continue to round 3. The report writer can note the saturation if it matters.
- Parallelism discipline: one message per round with all 5 Agent calls. Never serialize.