feat(review): fan multi-skill workers out into parallel single-skill runs#1651
feat(review): fan multi-skill workers out into parallel single-skill runs#1651peyton-alt wants to merge 1 commit into
Conversation
…runs A worker configured with N skills previously joined them into one child's prompt: skills executed sequentially (or blended), so selecting more skills made the user wait for the SUM of their durations. Measured live: a two-skill claude worker ran ~9 minutes as one child. explodeSkillWorkers splits each multi-skill worker into one worker per skill at plan time (keys like claude-code:review, deduped against existing workers), so skills run concurrently as ordinary slots — the wait becomes the slowest skill. Two exploded workers also mean the judge consolidates per-skill reports, extending the crew+judge value prop to single-agent multi-skill profiles. --agent now selects ALL of that agent's workers as a filtered crew (previously an ambiguity error), running the single-agent path only when exactly one worker matches. Same-agent SAME-model exploded workers defeat the existing agent+model session matching (assignments could cross, attributing tokens and transcripts to the wrong skill). AgentRun gains Skills, propagated through planned runs and both run paths, and the matcher requires skill-set agreement when both sides carry skills — mirroring the same-agent different-model disambiguation from #1313. Verified end-to-end with a claude shim: a two-skill profile spawns two one-skill children in parallel (~3s wall for both) plus the judge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 116f0cd95d56
There was a problem hiding this comment.
Pull request overview
This PR improves entire review orchestration by splitting (“fanning out”) multi-skill workers into parallel single-skill runs, and by propagating skill metadata end-to-end so lifecycle sessions can be matched back to the correct worker when agent+model are identical. It also adjusts --agent selection to run a filtered crew of all matching workers instead of erroring on ambiguity.
Changes:
- Plan-time fan-out: multi-skill worker configs are exploded into one worker per skill (parallel slots), including support for
--agentfiltering across all of an agent’s workers. - Session/run discrimination:
AgentRunnow carriesSkills, and manifest session matching requires skill-set agreement when both run and session state have skills. - Tests + docs updates: adds focused unit tests for fan-out and skills-based disambiguation; updates review command architecture docs.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| docs/architecture/review-command.md | Documents skill fan-out behavior, --agent selection semantics, and skills-based session matching. |
| cmd/entire/cli/review/types/sink.go | Extends AgentRun with Skills to carry per-worker skill metadata through summaries/sinks. |
| cmd/entire/cli/review/run.go | Populates AgentRun.Skills for single-agent runs and adds optional reviewer skill metadata plumbing. |
| cmd/entire/cli/review/run_multi.go | Threads Skills through multi-agent orchestration state and planned-run construction. |
| cmd/entire/cli/review/profile.go | Adds selectProfileWorkers to support resolving --agent selectors to multiple workers. |
| cmd/entire/cli/review/manifest.go | Updates session matching to include skill-set discrimination; adds stringSetsEqual. |
| cmd/entire/cli/review/manifest_test.go | Adds adversarial ordering test to prevent cross-assignment without skill discrimination. |
| cmd/entire/cli/review/fanout.go | Implements fan-out (explodeSkillWorkers) and --agent override application (applyAgentOverride). |
| cmd/entire/cli/review/fanout_internal_test.go | Unit tests for fan-out behavior and skill propagation into planned runs. |
| cmd/entire/cli/review/cmd.go | Wires fan-out into runReview flow and adds reviewer skill metadata adapter method. |
| cmd/entire/cli/review/cmd_test.go | Verifies multi-skill fan-out spawns one run per skill and --agent runs all exploded workers. |
| `entire review --models` lists the models each review-runner agent advertises via the optional `agent.ModelLister` capability (`cmd/entire/cli/agent/model_lister.go`). claude-code returns a curated list of real aliases (opus/sonnet/haiku); Pi enumerates live by shelling out to `pi --list-models`. Agents whose CLI has no enumeration command (codex, gemini) do not implement `ListModels`, so the picker offers only Default + Custom. The `--model` flag still forwards any value the agent CLI accepts. | ||
|
|
||
| The profile-level `task` is the shared work item. Each `agents` map entry is a worker id. For simple entries the worker id is also the agent name; to run the same agent more than once, use aliases and set `agent` plus `model`. Per-worker `skills`, `prompt`, and `model` adapt that task to agent-specific mechanics. Pi is a prompt/model-driven worker (`pi --mode json --print [--model ...]`) rather than a slash-command worker. Settings fields: `EntireSettings.ReviewProfiles` and `EntireSettings.ReviewDefaultProfile` in `cmd/entire/cli/settings/settings.go`. The old top-level `review` map is parse-tolerated and can be exposed as a legacy `general` profile when no `review_profiles` are configured. | ||
| The profile-level `task` is the shared work item. Each `agents` map entry is a worker id. A worker configured with multiple `skills` is exploded at plan time into one worker per skill (keys like `claude-code:review`), so skills run concurrently — the wait is the slowest skill, not the sum — and each exploded worker's session is matched back via the skills recorded on session state (`ReviewSkills`), which disambiguates same-agent same-model workers. `--agent <name>` selects ALL of that agent's workers (a filtered crew), running single-agent only when exactly one matches. For simple entries the worker id is also the agent name; to run the same agent more than once, use aliases and set `agent` plus `model`. Per-worker `skills`, `prompt`, and `model` adapt that task to agent-specific mechanics. Pi is a prompt/model-driven worker (`pi --mode json --print [--model ...]`) rather than a slash-command worker. Settings fields: `EntireSettings.ReviewProfiles` and `EntireSettings.ReviewDefaultProfile` in `cmd/entire/cli/settings/settings.go`. The old top-level `review` map is parse-tolerated and can be exposed as a legacy `general` profile when no `review_profiles` are configured. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 4c6f584. Configure here.
| profile.Agents = nonZeroAgentConfigs(profile.Agents) | ||
| // Fan out multi-skill workers into one worker per skill so skills run | ||
| // concurrently: the wait is the slowest skill, not the sum. | ||
| profile = explodeSkillWorkers(profile) |
There was a problem hiding this comment.
Judge loses worker model after explosion
Medium Severity
When explodeSkillWorkers runs before judge resolution, a multi-skill worker’s map key disappears. If judge.agent names that worker id and the judge has no explicit model, profileJudge no longer finds the worker entry and skips inheriting the worker’s configured model, so synthesis may run on a default model instead of the profile’s.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4c6f584. Configure here.


https://entire.io/gh/entireio/cli/trails/772
Stacked on #1647 — review only the top commit; retarget to main after #1647 merges.
Problem
A worker configured with N skills joined them into one child's prompt: the skills ran sequentially (or blended into one muddled pass), so selecting more skills grew the wait linearly. Measured live: a two-skill claude worker took ~9 minutes as a single child. The parallel machinery already existed one level up (worker slots fan out in
run_multi); multi-skill selection just never used it.Changes
explodeSkillWorkers: at plan time, each multi-skill worker becomes one worker per skill (keys likeclaude-code:review, deduped against existing worker names; agent/model/prompt preserved, explicitAgentset). Wait becomes max(skills) instead of sum(skills). Two exploded workers also engage the judge, extending crew+judge consolidation to single-agent multi-skill profiles.--agentselects a filtered crew: all of that agent's workers run (previously: ambiguity error). Single-agent path only when exactly one worker matches.AgentRungainsSkills(propagated through planned runs and both run paths), and the matcher requires skill-set agreement when both sides carry skills (session.State.ReviewSkillsis recorded fromENTIRE_REVIEW_SKILLSby the lifecycle hook). Mirrors Add Pi review-runner adapter #1313's different-model disambiguation, with an adversarially-ordered test that fails without the discriminator.Testing
mise run test(7,590),test:integration(390), canary — green🤖 Generated with Claude Code
Note
Medium Risk
Touches review orchestration,
--agentsemantics, and manifest/session attribution; behavior is well covered by tests but wrong matching would mis-attribute findings.Overview
Multi-skill workers now run in parallel instead of one child that runs every skill together. At plan time,
explodeSkillWorkerssplits each worker with more than one skill into separate workers (keys likeworker:skill-slug), so wall time tracks the slowest skill, not the sum. Model, prompt, and agent binding are preserved; keys are deduped so existing workers are not overwritten.--agentbehavior changes after explosion:applyAgentOverride/selectProfileWorkersreturn every worker for that agent. One match still uses the single-agent path; several exploded workers narrow the profile and run through the normal multi-reviewer flow (including judge when applicable), instead of failing on ambiguity.Manifest and run summaries carry skills on
AgentRunand planned runs (ReviewerSkillson configured reviewers). Session linking comparesrun.Skillstosession.State.ReviewSkillswhen both sides have data, so same-agent, same-model parallel skill runs do not swap transcripts or tokens.Reviewed by Cursor Bugbot for commit 4c6f584. Configure here.