Remove legacy reviewer loop, enable multi-agent reviewers - #678
Conversation
Replace the sequential legacy reviewer loop with wave-based multi-agent reviewer execution. Reviewers now run as part of the dependency graph alongside other agents, after their phase-specific predecessors. Changes: - Wire reviewers into multi-agent waves via include_reviewers=True - Remove _PHASE_REVIEWERS (string-based) and _REVIEWED_PHASES from pipelines.py - Replace legacy reviewer spawn loop with verdict file reading after multi-agent execution completes - Update _build_agent_prompt to delegate reviewer roles to the detailed _build_review_prompt with criteria and verdict format - Fix reviewer dependencies for plan phase: add TASK_PLANNER and RISK_ANALYST alongside INTEGRATOR so reviewers run after the correct predecessors in each phase (build_from_roles filters to in-set deps) Execution order: - Plan: architect -> task_planner+risk_analyst -> reviewers - Implement: coder -> tester+documenter -> integrator -> reviewers
There was a problem hiding this comment.
Review: Remove legacy reviewer loop, enable multi-agent reviewers
I reviewed both changed files and the surrounding context (dependency graph builder, verdict file handling, phase configuration). Overall the direction is good — removing ~150 lines of sequential reviewer spawning in favor of wave-based execution is a clear simplification. However, there are two issues that should be addressed before merging.
Bug: Stale verdict files are no longer cleaned before review cycles
Severity: High — correctness issue
Files: orchestrator/routes/pipelines.py, lines 2722-2748
The old code explicitly deleted stale verdict files before spawning reviewers (the removed block at old lines ~2739-2756):
# Delete stale verdict files before spawning reviewers
for rtype in reviewer_types:
verdict_path = worktree_repo_path / verdict_rel
if verdict_path.exists():
verdict_path.unlink()The new code reads verdict files after _run_multi_agent_phase() completes but never cleans them up beforehand. This creates two failure modes:
-
Re-review cycles read stale verdicts. If a reviewer agent fails to write its verdict (crash, timeout, etc.), the previous cycle's verdict file persists.
_read_review_verdict()returns the old verdict, which may say "approved" even though the reviewer never ran in this cycle. This silently skips needed revisions. -
First run after a pipeline restart. If the pipeline restarts from a checkpoint, stale verdict files from the previous run remain on disk. The new reviewers' verdicts should overwrite them in the happy path, but any reviewer failure silently inherits the old verdict.
Fix: Add verdict file cleanup before _run_multi_agent_phase() is called, similar to the old code. This can be done once at the top of the verdict-reading block or before the multi-agent phase call. Something like:
# Before calling _run_multi_agent_phase, clean stale verdicts
for role in reviewer_roles:
rtype = role.value.replace("reviewer_", "", 1).replace("_", "-")
verdict_rel = _verdict_path_for_type(...)
verdict_path = worktree_repo_path / verdict_rel
if verdict_path.exists():
verdict_path.unlink(missing_ok=True)You'll need to resolve the reviewer_roles lookup before the multi-agent call or move the cleanup into _run_multi_agent_phase() itself.
Behavior change: "refine" phase lost its review cycle
Severity: Medium — silent behavior change, may be intentional
Files: orchestrator/routes/pipelines.py, lines 2725, 2793
The old code had:
_REVIEWED_PHASES = {"refine", "plan", "implement"}
_PHASE_REVIEWERS = {"refine": ["unified", "agent-design"], ...}The "refine" phase used to get a sequential review cycle with unified + agent-design reviewers. The new code only reads verdicts when use_multi_agent is true (line 2725), and use_multi_agent is only true for {"implement", "plan"} (line 2447-2450). The new _PHASE_REVIEWERS in agent_roles.py also has no "refine" entry.
So "refine" now hits break at line 2793 (non-multi-agent path) and advances without any review.
If this is intentional — because refine uses human checkbox review (HumanReviewMechanism.ISSUE_CHECKBOX) and the agent review was redundant — the PR description should say so explicitly. If it's unintentional, the refine phase just lost its review gate.
The docstring at line 2149 still references refine as a reviewed phase: "2. For reviewed phases (refine, plan): spawns a reviewer..." — this is now stale regardless of whether the change is intentional.
Minor: _build_agent_prompt returns early for reviewers, skipping phase restrictions
Severity: Low — likely acceptable
File: orchestrator/routes/pipelines.py, lines 1547-1558
The old code appended reviewer instructions to lines and then fell through to the "Phase Restrictions" and "Phase Completion" sections at lines 1567-1591. The new code does return _build_review_prompt(...) at line 1550, which means reviewer agents no longer receive:
- Phase restriction instructions (e.g., "You CAN push code" / "You CANNOT create PRs")
- Phase completion instructions
This is probably fine because _build_review_prompt() is self-contained and reviewers don't need push/PR restrictions (they only write verdict files). But worth confirming that the old reviewer prompt behavior intentionally omitted these sections — the old code included them by falling through, so this is a change.
Summary
| Issue | Severity | Blocking? |
|---|---|---|
| Stale verdict files not cleaned | High | Yes |
| Refine phase lost review cycle | Medium | Clarification needed |
| Reviewers skip phase restrictions | Low | No |
The stale verdict file issue is a correctness regression that should be fixed. The refine phase change needs explicit confirmation of intent.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Add verdict file cleanup before _run_multi_agent_phase() to prevent reading outdated verdicts when a reviewer crashes or the pipeline restarts from a checkpoint. Also update the _run_pipeline docstring to reflect that reviewed phases are now implement and plan (not refine).
There was a problem hiding this comment.
Thanks for the thorough review. Here's how I addressed each item:
1. Stale verdict files not cleaned — Fixed ✓
Agreed. Added verdict file cleanup before _run_multi_agent_phase() is called, inside the if use_multi_agent: block. The cleanup iterates over _PHASE_REVIEWERS for the current phase and deletes any existing verdict files, matching the pattern from the old code (with OSError exception handling). This prevents both failure modes identified: stale verdicts from crashed reviewers and leftover files after pipeline restart.
See commit 4f92088.
2. Refine phase lost its review cycle — Intentional
This is intentional. The refine phase uses HumanReviewMechanism.ISSUE_CHECKBOX (see phase_defaults.py:84) and is gated by the HITL checkpoint in _HITL_GATE_PHASES. The agent-based review cycle was redundant — the human reviews the refined output via issue checkboxes before the pipeline advances.
Additionally, _PHASE_REVIEWERS in agent_roles.py was designed without a "refine" entry because refine doesn't participate in multi-agent wave execution (use_multi_agent is only true for implement/plan).
I've updated the _run_pipeline docstring to reflect this: it now references "implement, plan" instead of "refine, plan" as reviewed phases.
3. Reviewers skip phase restrictions — Acceptable, no change
Agreed this is acceptable. _build_review_prompt() is self-contained with reviewer-specific instructions. Reviewers only read code and write verdict files — they don't push code, create PRs, or need phase restriction instructions. The old code included these sections by fall-through, but they were never relevant to reviewer behavior.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
Update the DAG visualizer to display agents grouped by their execution wave from the dependency graph, instead of a flat list sorted by enum order. Each wave renders on its own line(s), making the execution order and parallelism immediately visible. Example output for implement phase: ✓ coder ✓ tester ✓ documenter ✓ integrator ▶ reviewer_unified ○ reviewer_code ○ reviewer_contract ○ reviewer_agent_design Falls back to flat list for phases without defined agent roles.
… into egg/remove-legacy-reviewer-loop
This comment has been minimized.
This comment has been minimized.
|
@james-in-a-box Point 2 here #678 (review) is technically correct, but we do want the refine phase to have an auto-review cycle. Let's update that. For point 3, , reviewers absolutely should not skip phase restrictions! They should only be able to write verdict files, or in the case of the contract reviewer they should also be able to update the contract (marking items as done). |
Remove unused AgentRole import from dag_visualizer.py, rename ambiguous variable 'l' to 'line' in test_dag_visualizer.py (E741), and update test_all_roles assertion to match the 13 agent roles now defined in the AgentRole enum.
There was a problem hiding this comment.
Fixed remaining lint and test issues:
- Unused import: Removed
AgentRolefromdag_visualizer.py(unused after refactor to_compute_wave_order) - E741 lint errors: Renamed ambiguous variable
l→lineintest_dag_visualizer.py(12 occurrences) - Stale test assertion: Updated
test_all_rolesintest_models.pyfrom== 6to== 13to match the new agent roles added by this PR
All 386 orchestrator tests pass and ruff check is clean.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review: Remove legacy reviewer loop, enable multi-agent reviewers
Reviewed the delta since f1c0179 (commits 4f92088 and 5f0c805, plus merge commit 656eec3). Two changes: verdict file cleanup fix in pipelines.py and wave-based agent grouping in dag_visualizer.py.
Previous feedback verification
1. Stale verdict files (High) — Fixed correctly.
The cleanup block at pipelines.py:2453-2480 correctly iterates _PHASE_REVIEWERS for the current phase, constructs verdict paths using the same role.value.replace("reviewer_", "", 1).replace("_", "-") + _verdict_path_for_type() pattern as the reading code at line 2765, and deletes them with OSError handling. The cleanup runs inside the if use_multi_agent: block, before _run_multi_agent_phase() is called. This addresses both failure modes (crashed reviewer, pipeline restart).
2. Refine phase lost review cycle (Medium) — Confirmed intentional, docstring updated.
The _run_pipeline docstring at line 2148 now correctly references "implement, plan" instead of "refine, plan". Refine is gated by HumanReviewMechanism.ISSUE_CHECKBOX so the agent review was redundant.
3. Reviewers skip phase restrictions (Low) — Acknowledged as acceptable, no change needed.
All three items from the previous review are addressed.
New code: _compute_wave_order in dag_visualizer.py
The new function at dag_visualizer.py:107-158 groups agents by execution wave using the dependency graph for display purposes. The implementation is sound:
- Graceful fallback:
ImportErrorfrom missingegg_contractsandValueErrorfrom unrecognized phases both fall back to[agents](flat list). This keeps the visualizer decoupled from the contracts library. - Cross-enum compatibility: The function imports
egg_contracts.agent_roles.AgentRole(which lacks genericREVIEWER) but operates on agents typed withmodels.AgentRole(which hasREVIEWER). The.valuestring comparison at line 138 bridges this correctly, and theremainingcatch-all at line 151 handles agents not present in the dependency graph (like genericREVIEWER). - No duplicate agent issue:
agent_by_role_valuedict would silently drop duplicate roles, but each role appears at most once per phase execution by design.
Both call sites (_render_phase_box at line 191 and render_phase_detail at line 396) correctly use the wave groups for rendering.
New code: Tests in test_dag_visualizer.py
Six new tests in TestWaveGrouping cover:
- Wave ordering for implement and plan phases (integration tests via
render_pipeline_dag) - Direct
_compute_wave_orderunit tests for implement phase - Fallback for unknown phases
- Unrecognized agents appended at end
- Ordering assertion (reviewers after planners)
All 44 tests pass (verified locally).
One minor note (non-blocking)
Importing _PHASE_REVIEWERS (private symbol) in pipelines.py: This happens twice (lines 2458 and 2755), importing a leading-underscore dict from egg_contracts.agent_roles. The dict is effectively part of the module's contract since get_roles_for_phase() delegates to it, but using the public function would be cleaner. Not blocking because: (a) pipelines.py already does this at line 2755 in the original commit, and (b) the cleanup code at line 2458 needs to iterate the same reviewer list as the reading code, so consistency is more important here. Consider exposing get_reviewers_for_phase() as a public helper in a follow-up if this pattern grows.
No blocking issues found. The feedback from the previous review has been properly addressed. The new DAG visualization code is well-structured with good test coverage and appropriate fallback behavior.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review: Remove legacy reviewer loop, enable multi-agent reviewers
Reviewed the delta since 656eec3 (commit 3e70faa). The new commit fixes lint issues (unused AgentRole import in dag_visualizer.py, l → line renames in tests) and updates the test_all_roles assertion from 6 to 13 roles. These changes are correct and non-controversial.
However, the two issues raised by the repo owner after my previous approval have not been addressed. Both are explicit requests from @jwbron in this comment.
1. Refine phase must have auto-review cycle — NOT FIXED
Severity: High — owner-requested feature gap
Files: shared/egg_contracts/agent_roles.py (lines ~487-496), orchestrator/routes/pipelines.py (line ~2450)
Owner's request: "we do want the refine phase to have an auto-review cycle"
Current state:
_PHASE_REVIEWERShas no"refine"entry_PHASE_ROLEShas no"refine"entryuse_multi_agentis only true for{"implement", "plan"}- The refine phase hits
breakat the# Non-multi-agent phases — advance directlypath (line ~2822), skipping review entirely
What needs to happen:
- Add a
"refine"entry to_PHASE_REVIEWERSinagent_roles.py(likely[REVIEWER_UNIFIED, REVIEWER_AGENT_DESIGN]matching the old_PHASE_REVIEWERSfor refine) - Either add
"refine"to theuse_multi_agentcondition inpipelines.py, or implement a separate review-only path for phases that use single-agent execution but still need reviewer verdicts - If refine doesn't need full multi-agent wave execution (no coder/tester/etc.), you may need a lighter path that only spawns reviewers after the single-agent refine worker completes
2. Reviewers MUST receive phase restrictions — NOT FIXED
Severity: High — owner-requested security/correctness fix
Files: orchestrator/routes/pipelines.py (lines 1548-1558)
Owner's request: "reviewers absolutely should not skip phase restrictions! They should only be able to write verdict files, or in the case of the contract reviewer they should also be able to update the contract (marking items as done)."
Current state: _build_agent_prompt does return _build_review_prompt(...) at line 1550 for any role_value.startswith("reviewer_"), bypassing the "Phase Restrictions" and "Phase Completion" sections at lines 1567-1591.
What needs to happen:
The _build_review_prompt() function should include phase restriction instructions. The restrictions for reviewers should state:
- You CAN write verdict files to
.egg-state/reviews/ - You CANNOT push code, create PRs, or modify source files
- (For contract reviewer specifically) You CAN update the contract in
.egg-state/contracts/
This can be done either by:
- Adding a restrictions section inside
_build_review_prompt(), or - Removing the early
returnso reviewers fall through to the restrictions section, and adjusting the restrictions text to be reviewer-appropriate
Additionally, the REVIEWER_CONTRACT_ROLE definition in agent_roles.py has .egg-state/contracts/ in blocked_write (via _REVIEWER_BLOCKED_WRITE). Per the owner's comment, the contract reviewer should be able to update the contract. The file access pattern needs to be updated — either remove .egg-state/contracts/ from the contract reviewer's blocked list, or give REVIEWER_CONTRACT_ROLE its own blocked_write list that excludes .egg-state/contracts/ while keeping the other blocks.
3. New delta changes (lint fixes + test update) — Fine
The actual code in commit 3e70faa is correct:
- Removing unused
AgentRoleimport fromdag_visualizer.py— good cleanup - Renaming
l→lineto fix E741 lint errors — correct, all 12 occurrences updated consistently - Updating
test_all_rolesfrom== 6to== 13with explicit assertions for all 7 new roles — correct, matches theAgentRoleenum
Summary
| Issue | Severity | Status |
|---|---|---|
| Refine phase needs auto-review cycle | High | Not addressed (owner requested) |
| Reviewers must receive phase restrictions | High | Not addressed (owner requested) |
| Contract reviewer needs contract write access | Medium | Not addressed (implied by owner comment) |
| Lint fixes + test update | — | Correct |
The owner's feedback was posted after my previous approval and is unambiguous: both the refine review cycle and reviewer phase restrictions are required changes. Neither has been implemented in the new commits.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…ontract write access
|
Addressed all three items from @jwbron's feedback: 1. Refine phase auto-review cycle — FixedAdded 2. Reviewers receive phase restrictions — FixedAdded a "Phase Restrictions" section to
3. Contract reviewer write access — FixedCreated a dedicated All 363 orchestrator tests pass. — Authored by egg |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review: Remove legacy reviewer loop, enable multi-agent reviewers
Reviewed the delta since 3e70faa (commit 5417610). This commit addresses the three items from @jwbron's feedback: refine phase auto-review cycle, reviewer phase restrictions, and contract reviewer write access.
Previous feedback verification
1. Refine phase auto-review cycle — Fixed.
_PHASE_REVIEWERS in agent_roles.py:660-663 now includes "refine": [REVIEWER_UNIFIED, REVIEWER_AGENT_DESIGN]. In pipelines.py, the verdict-reading block (lines 2767-2917) now applies to all phases with reviewers by looking up _PHASE_REVIEWERS rather than checking a hardcoded _REVIEWED_PHASES set. For non-multi-agent phases like refine, reviewers are spawned as individual containers (lines 2782-2860) after the worker completes. The docstring at line 2160 is updated to reflect refine as a reviewed phase.
2. Reviewers receive phase restrictions — Fixed.
_build_review_prompt() now includes a "Phase Restrictions" section (lines 1018-1031) explicitly stating what reviewers CAN and CANNOT do. The contract reviewer gets an additional line permitting .egg-state/contracts/ access.
3. Contract reviewer write access — Fixed.
A dedicated _REVIEWER_CONTRACT_BLOCKED_WRITE list (lines 474-481) excludes .egg-state/contracts/ while retaining all other blocks. REVIEWER_CONTRACT_ROLE uses this list and adds .egg-state/contracts/ to allowed_write.
Bug: review_cycle off-by-one in single-agent reviewer path
Severity: Medium — correctness issue affecting re-review prompts
File: orchestrator/routes/pipelines.py, line 2814
The old sequential reviewer code passed review_cycle + 1 to _build_review_prompt():
review_cycle=review_cycle + 1,The new single-agent reviewer path at line 2814 passes review_cycle without the increment:
review_cycle=review_cycle,_build_review_prompt was designed for 1-indexed cycle numbers (default parameter is review_cycle: int = 1 at line 944). It uses the value in two places:
-
Display (line 968):
f"Review cycle: {review_cycle}"— the reviewer sees "Review cycle: 0" on the first cycle instead of "1". Cosmetic but confusing. -
Prior feedback inclusion (line 991):
if review_cycle > 1 and prior_feedback:— On the second review cycle (review_cycle=1from pipeline state), this condition isFalse, so prior feedback from the first review is not included in the re-review prompt. The reviewer doesn't see what they flagged last time. This only triggers starting fromreview_cycle=2(third cycle), losing one cycle of feedback context.
The multi-agent path has the same issue (_build_agent_prompt at line 1659 also passes review_cycle without +1), but that's pre-existing. The single-agent path is new code and should match the old behavior.
Fix: Change line 2814 to review_cycle=review_cycle + 1.
Reviewers spawned sequentially, not in parallel (single-agent path)
Severity: Low — performance, not correctness
File: orchestrator/routes/pipelines.py, lines 2802-2860
The new single-agent reviewer spawning loop iterates over reviewer_roles and calls _spawn_and_wait() for each reviewer sequentially. The old code did the same thing, so this isn't a regression. However, since the reviewers are independent (they read the same draft and write to separate verdict files), they could run in parallel — the multi-agent path already does this via wave execution. Not blocking, but worth noting as a future optimization for refine phase review latency.
Summary
| Issue | Severity | Blocking? |
|---|---|---|
review_cycle off-by-one (single-agent path) |
Medium | Yes |
| Sequential reviewer spawning | Low | No |
The three owner-requested changes are properly implemented. The off-by-one in review_cycle should be fixed before merge — it causes re-review prompts to omit prior feedback for one cycle.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The pipeline tracks review_cycle as 0-indexed, but _build_review_prompt expects 1-indexed values (default=1). Without the +1 conversion: - First cycle displays "Review cycle: 0" instead of "1" - Second cycle omits prior feedback (review_cycle > 1 check fails) Fix both the single-agent reviewer path (line 2814) and the multi-agent path via _build_agent_prompt (line 1571).
|
Fixed the Both the single-agent reviewer path (line 2814) and the multi-agent path via Re: sequential reviewer spawning — agreed this is a future optimization opportunity for the refine phase. The current behavior matches the old sequential code, so no regression. All 363 orchestrator tests pass. — Authored by egg |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review: Remove legacy reviewer loop, enable multi-agent reviewers
Reviewed the delta since 5417610 (commit 4931697). Single change: review_cycle off-by-one fix.
Previous feedback verification
review_cycle off-by-one in reviewer prompt construction — Fixed correctly.
Both call sites now pass review_cycle + 1 to _build_review_prompt():
-
Multi-agent path (
_build_agent_prompt, line 1571):review_cycle=review_cycle + 1— when_build_agent_promptreceives a 0-indexed cycle number and delegates to_build_review_promptfor reviewer roles, the +1 converts to the expected 1-indexed convention. -
Single-agent path (line 2814):
review_cycle=review_cycle + 1— direct calls to_build_review_promptin the sequential reviewer spawning loop also apply the conversion.
I verified that all other review_cycle usages in the file are consistent:
_build_phase_prompt(line 1155) receives 0-indexed values and usesreview_cycle > 0to gate feedback inclusion — correct, no change needed.- Logger calls and storage updates (lines 2885, 2896, 2905, 2912) all use
review_cycle + 1for display/persistence — consistent. - The circuit breaker at line 2891 (
review_cycle + 1 >= max_cycles) correctly compares 1-indexed cycle count against the configured maximum.
No new issues introduced.
Full PR status
All issues raised across the review history are now resolved:
| Issue | Resolution | Status |
|---|---|---|
| Stale verdict files not cleaned | Cleanup block before _run_multi_agent_phase() |
Fixed (commit 4f92088) |
| Refine phase auto-review cycle | Added to _PHASE_REVIEWERS, reviewer spawning for single-agent phases |
Fixed (commit 5417610) |
| Reviewer phase restrictions | Restrictions section in _build_review_prompt() |
Fixed (commit 5417610) |
| Contract reviewer write access | Dedicated _REVIEWER_CONTRACT_BLOCKED_WRITE list |
Fixed (commit 5417610) |
review_cycle off-by-one |
Both paths pass review_cycle + 1 |
Fixed (commit 4931697) |
— Authored by egg
|
egg review completed. View run logs 12 previous review(s) hidden. |
Remove the legacy sequential reviewer loop and enable multi-agent
reviewers by default in the SDLC pipeline.
The pipeline had two separate reviewer systems: a legacy string-based
reviewer loop that spawned reviewers sequentially after phase completion,
and a newer AgentRole-based reviewer system designed for wave-based
multi-agent execution but never wired in. This caused confusion in
pipeline visualization and duplicate infrastructure.
This change wires reviewer roles into the multi-agent dependency graph
via
get_roles_for_phase(phase, include_reviewers=True), removes thelegacy reviewer loop (~150 lines), and replaces it with compact verdict
file reading after multi-agent execution completes. Reviewer role
dependencies are updated so they run after the correct predecessors
in each phase: INTEGRATOR for implement, TASK_PLANNER/RISK_ANALYST
for plan (the graph builder filters to only deps present in the role set).
Execution order is now:
Issue: none
Test plan:
build_dependency_graph().compute_waves()Authored-by: egg