Skip to content

feat(review): fan multi-skill workers out into parallel single-skill runs#1651

Open
peyton-alt wants to merge 1 commit into
feat/review-child-contextfrom
feat/review-skill-fanout
Open

feat(review): fan multi-skill workers out into parallel single-skill runs#1651
peyton-alt wants to merge 1 commit into
feat/review-child-contextfrom
feat/review-skill-fanout

Conversation

@peyton-alt

@peyton-alt peyton-alt commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

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 like claude-code:review, deduped against existing worker names; agent/model/prompt preserved, explicit Agent set). 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.
  • --agent selects a filtered crew: all of that agent's workers run (previously: ambiguity error). Single-agent path only when exactly one worker matches.
  • Session matching by skills: same-agent same-model exploded workers defeat the agent+model matcher — assignments could cross, attributing tokens/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 (session.State.ReviewSkills is recorded from ENTIRE_REVIEW_SKILLS by 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

  • TDD throughout (explosion, override semantics, cross-assignment, propagation — each watched fail first)
  • mise run test (7,590), test:integration (390), canary — green
  • Shim smoke: a two-skill profile spawns two one-skill children in parallel (~3s wall for both) plus one judge invocation

🤖 Generated with Claude Code


Note

Medium Risk
Touches review orchestration, --agent semantics, 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, explodeSkillWorkers splits each worker with more than one skill into separate workers (keys like worker: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.

--agent behavior changes after explosion: applyAgentOverride / selectProfileWorkers return 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 AgentRun and planned runs (ReviewerSkills on configured reviewers). Session linking compares run.Skills to session.State.ReviewSkills when 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.

…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
Copilot AI review requested due to automatic review settings July 6, 2026 16:49
@peyton-alt peyton-alt requested a review from a team as a code owner July 6, 2026 16:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 --agent filtering across all of an agent’s workers.
  • Session/run discrimination: AgentRun now carries Skills, 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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4c6f584. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants