Skip to content

Add cross-agent messaging and concurrent phase execution#1031

Merged
jwbron merged 20 commits intomainfrom
egg/issue-1027-concurrent-execution
Mar 11, 2026
Merged

Add cross-agent messaging and concurrent phase execution#1031
jwbron merged 20 commits intomainfrom
egg/issue-1027-concurrent-execution

Conversation

@james-in-a-box
Copy link
Contributor

Summary

Implement the core infrastructure for real-time inter-agent communication and concurrent phase execution in the SDLC pipeline, as designed in the analysis and plan for issue #1027.

  • Message bus: In-memory per-pipeline message store with REST endpoints for send, poll, and status. Agents communicate via egg-orch message send/poll/status CLI commands.
  • Consensus protocol: ConsensusEvaluator tracks per-agent readiness states (WORKING, READY, BLOCKED, OBJECTING). Phase advances only when all agents signal READY. Agents signal via egg-orch signal readiness.
  • Concurrent executor: ConcurrentPhaseExecutor spawns all agents simultaneously with per-agent worktree branches. Handles single/multi-agent failures with HITL escalation.
  • Config: Opt-in via PipelineConfig.concurrent_execution (default false). Existing pipelines are unaffected.
  • Integration: MESSAGE_SENT/MESSAGE_RECEIVED events, checkpoint capture of inter-agent messages, concurrent status monitoring in pipeline status endpoint.

Recovers all .egg-state files (analysis, plan, contract, reviews) and tests/docs from the failed pipeline run.

Closes #1027

Issue: #1027

Test plan:

  • All 69 new and existing tests pass (test_concurrent_status, test_concurrent_integration, test_checkpoint_inter_agent, test_checkpoint_cli_inter_agent, test_events, test_multi_agent)
  • Lint clean (ruff check passes on all modified files)
  • Backward compatible: concurrent_execution defaults to false

egg added 16 commits March 11, 2026 05:08
Container 3a041c2dae96d2b8073c88b42a8929104ee572a9d3b6d977a10fad63f7b9ded8 exited with uncommitted changes.
This commit preserves the agent's work-in-progress.

Authored-by: egg
Container d3c23677754833b2e4107fa511a4f0db117f5bfa5e538b859fa9f313eda367ec exited with uncommitted changes.
This commit preserves the agent's work-in-progress.

Authored-by: egg
Container f9ac6b869d66957cc98f5b2a655792b042fb689696df7d74a6160a3c0123d198 exited with uncommitted changes.
This commit preserves the agent's work-in-progress.

Authored-by: egg
Container 4e8629d8877351ae32193aaa6b35add466ddbc312b8dbdfeeb57f570451986cb exited with uncommitted changes.
This commit preserves the agent's work-in-progress.

Authored-by: egg
Implement the core infrastructure for real-time inter-agent communication
and concurrent phase execution in the SDLC pipeline (issue #1027).

New modules:
- orchestrator/message_store.py: Thread-safe in-memory message bus
- orchestrator/routes/messages.py: REST endpoints for send/poll/status
- orchestrator/consensus.py: Consensus evaluator with readiness states
- orchestrator/concurrent_executor.py: Concurrent phase executor

Modified:
- models.py: Add concurrent config fields to PipelineConfig
- events.py: Add MESSAGE_SENT/MESSAGE_RECEIVED event types
- api.py: Register messages blueprint
- signals.py: Add readiness signal handler for consensus
- client.py: Add message and readiness client methods
- types.py: Add MessageType, ReadinessState, MessageData, ReadinessData
- orch_cli.py: Add message and signal readiness CLI commands
- multi_agent.py: Add is_concurrent_execution() helper

Also includes .egg-state files (analysis, plan, contract, reviews),
tests, and docs recovered from the failed pipeline.

Issue: #1027
Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

Review: Cross-agent messaging and concurrent phase execution

Thorough review of all 36 changed files (4997 additions). The design is sound and backward-compatible. Implementation is generally clean. I found several issues ranging from correctness bugs to robustness gaps.


Blocking Issues

1. poll_messages endpoint: unvalidated limit parameter crashes on bad input
orchestrator/routes/messages.py:135

limit = int(request.args.get("limit", "100"))

If a client sends ?limit=abc, this throws a ValueError that is not caught, returning a 500 error. The send_message endpoint validates its inputs; poll_messages should too. Wrap in try/except or use a validation helper.

2. poll_messages and message_status endpoints skip pipeline existence validation
orchestrator/routes/messages.py:124-159

The send_message endpoint (line 79-83) validates the pipeline exists via get_state_store().load_pipeline(). But poll_messages and message_status skip this entirely. While an empty result is returned for nonexistent pipelines (not a crash), this inconsistency means:

  • No 404 for a typo in the pipeline ID — the client silently gets empty results and can't distinguish "no messages" from "wrong pipeline"
  • pipeline_id is not validated against InvalidPipelineIdError (path traversal protection that other endpoints enforce)

Add pipeline validation to both GET endpoints, matching the POST pattern.

3. handle_readiness_signal emits misleading event types
orchestrator/routes/signals.py:624-625

emit_event(
    EventType.AGENT_COMPLETED if state_str == "READY" else EventType.AGENT_STARTED,
    ...
)

This re-uses AGENT_COMPLETED and AGENT_STARTED for readiness state changes, which is semantically wrong:

  • AGENT_STARTED means a container was started, not that an agent transitioned to WORKING/BLOCKED/OBJECTING
  • AGENT_COMPLETED means a container exited, not that an agent signaled READY
  • SSE consumers and monitoring code subscribed to these events will receive false signals

This should emit a new READINESS_CHANGED event type (or use MESSAGE_SENT/MESSAGE_RECEIVED which are already defined), not repurpose container lifecycle events. Any downstream listener that tracks container state will get corrupted counts.

4. Messages are never cleared on phase transitions

The MessageStore.clear() and ConsensusEvaluator.clear() methods exist but are never called anywhere. The docstring on MessageStore says "Messages are ephemeral within a phase" and MessageStore.clear says "e.g., on phase transition", but grep across the entire orchestrator shows zero call sites for either clear method.

This means:

  • Messages from a previous phase leak into the next phase
  • Consensus state from a previous phase leaks, potentially causing false consensus evaluation
  • The in-memory store grows unboundedly across the pipeline lifecycle

Wire clear() calls into the phase transition logic (likely in the phase advancement handler or the executor).

5. _get_concurrent_status uses relative imports that may fail at runtime
orchestrator/routes/pipelines.py:886, 902

from ..message_store import get_message_store  # type: ignore[import-not-found]
from ..consensus import get_consensus_evaluator  # type: ignore[import-not-found]

The # type: ignore[import-not-found] suppressions and except (ImportError, Exception) pattern are defensive. However, the existing imports in this file use .. relative imports (consistent). The real concern is the broad except (ImportError, Exception) which silences ALL exceptions including bugs like TypeError, AttributeError, etc. during the message store or consensus operations. This makes debugging very hard.

Change to except ImportError for the import, and let runtime errors from get_message_store() / get_consensus_evaluator() propagate. A bug in the message store shouldn't silently return zeros.


Non-Blocking Issues

6. Message.id uses truncated UUID — collision risk
orchestrator/message_store.py:29

id: str = Field(default_factory=lambda: str(uuid.uuid4())[:16])

Truncating a UUID4 to 16 hex chars gives 64 bits of randomness. For a per-pipeline message bus with tens of messages, collisions are unlikely but:

  • The since_id filter linearly scans for a matching ID. If two messages share an ID (even across pipelines, since IDs aren't namespaced), the cursor breaks
  • The architecture doc specified auto-incrementing integer IDs, which are simpler and guarantee ordering

Consider using full UUIDs, or switch to sequential integers as designed, which also gives trivial O(1) since_id filtering via binary search or index offset.

7. since_id filtering is O(n) linear scan
orchestrator/message_store.py:106-114

The get_messages() method performs a linear scan to find the since_id message. For a "tens of messages per phase" workload this is fine, but if an agent passes an invalid/expired since_id, the scan finds nothing and filtered stays empty — silently returning no messages. This is a subtle failure mode: an agent that passes a stale since_id from a previous phase (if messages aren't cleared) silently misses all new messages.

8. get_messages copies the full list under lock then filters outside lock
orchestrator/message_store.py:102-103

with self._lock:
    msgs = list(self._messages.get(pipeline_id, []))

This copies the entire message list on every poll. For expected volumes this is fine, but the pattern means filtering (since_id, role, limit) happens outside the lock on a snapshot. If a message is added between the copy and the role filter, it's missed — this is acceptable for an eventually-consistent polling model, just noting it.

9. _fetch_inter_agent_messages doesn't filter out self-sent broadcast messages correctly
gateway/checkpoint_handler.py:175-178

for msg in data.get("data", {}).get("messages", []):
    direction = "received"
    if msg.get("from_role") == agent_role:
        direction = "sent"

When an agent sends a broadcast (to_role="all"), the poll endpoint returns that message back to the sender (since to_role=="all" matches any role). The direction logic correctly marks it as "sent". However, the agent now sees its own broadcast messages when polling, which could confuse LLM agents that are instructed to "process messages from other agents."

The poll_messages endpoint could optionally exclude self-sent messages, or the checkpoint handler could document this behavior.

10. TokenUsage model: cache_write_tokens field name mismatch
tests/shared/egg_contracts/test_checkpoint_cli_inter_agent.py:253

TokenUsage(
    input_tokens=100,
    output_tokens=50,
    total_tokens=150,
    cache_read_tokens=0,
    cache_write_tokens=0,
)

Check whether the field is cache_write_tokens or cache_creation_tokens — the checkpoints.py model uses cache_creation_tokens in the field definition. If the model has cache_creation_tokens, this test will fail with a validation error (or succeed with extra="allow" but not actually set the right field). Verify and fix the field name.

11. Integration tests are mostly mock-based simulations, not testing actual components
orchestrator/tests/test_concurrent_integration.py

The "integration" tests for message exchange and consensus (e.g., TestConcurrentMessageExchange, TestConcurrentConsensusFlow) are pure Python logic simulations with local dicts — they don't actually exercise the MessageStore, ConsensusEvaluator, Flask routes, or any wiring between them. They're conceptual tests of the pattern, not the implementation.

The TestConcurrentPipelineStatus class does hit the Flask endpoint, which is good. Consider adding tests that use the actual MessageStore and ConsensusEvaluator classes rather than mock dictionaries.

12. Duplicate type definitions across modules
orchestrator/message_store.py:16-23 vs shared/egg_orchestrator/types.py:78-84
orchestrator/consensus.py:16-22 vs shared/egg_orchestrator/types.py:87-92

MessageType and ReadinessState are defined in both the orchestrator and shared packages. The orchestrator versions are plain classes/StrEnums, the shared versions are StrEnums. This duplication means:

  • If someone adds a new message type to one, they must remember the other
  • The orchestrator's MessageType is a plain class (not an enum), while the shared version is a StrEnum — they're not interchangeable

Consider importing from shared, or at minimum add a comment cross-referencing the duplicate.

13. _get_concurrent_status agent status extraction is fragile
orchestrator/routes/pipelines.py (around line 3757-3763 in the diff)

if phase_exec and hasattr(phase_exec, "agents"):
    agents_info = []
    for agent in phase_exec.agents:
        agents_info.append({
            "role": agent.role if hasattr(agent, "role") else str(agent),
            "status": agent.status.value if hasattr(agent, "status") else "unknown",
        })

The AgentExecution model has .role as an AgentRole enum. Using agent.role directly in the JSON will serialize the enum, not the string. It should be agent.role.value for consistency. The hasattr checks suggest uncertainty about the type — since PhaseExecution.agents is a list[AgentExecution], you can trust the type and use .role.value directly.

14. ConcurrentPhaseExecutor.get_agent_roles() is hardcoded
orchestrator/concurrent_executor.py:75-80

def get_agent_roles(self) -> list[AgentRole]:
    return [AgentRole.CODER, AgentRole.TESTER, AgentRole.DOCUMENTER]

This hardcodes the implement-phase roles. The architecture doc mentions the integrator should also participate in concurrent mode, but it's excluded here. This may be intentional (integrator spawns after consensus), but there's no dispatch integration — the ConcurrentPhaseExecutor doesn't consult the contract's get_next_dispatch() to determine which roles should run. For V1 this is acceptable but worth a TODO.

— Authored by egg

Copy link
Contributor Author

@james-in-a-box james-in-a-box bot left a comment

Choose a reason for hiding this comment

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

Contract Verification: PR #1031 — Cross-Agent Messaging and Concurrent Phase Execution

Verdict: Request Changes — 2 blocking gaps, 3 minor deviations.

Test Results

All 69 tests pass across 4 test files:

  • test_concurrent_integration.py — 11 passed
  • test_concurrent_status.py — 12 passed
  • test_checkpoint_inter_agent.py — 19 passed
  • test_checkpoint_cli_inter_agent.py — 8 passed
  • test_events.py — 15 passed
  • test_multi_agent.py — 4 passed

Lint clean (ruff check passes on all modified source files).


Phase 1: Message API and Agent SDK

Task Status Notes
1-1 Models + Events + Blueprint VERIFIED Message dataclass in message_store.py, MESSAGE_SENT/MESSAGE_RECEIVED in events.py, blueprint registered in api.py
1-2 MessageStore VERIFIED Thread-safe in-memory store with add/get-since/status/clear
1-3 REST endpoints VERIFIED send/poll/status in routes/messages.py with role validation and EventBus events
1-4 Client SDK + Types VERIFIED send_message/poll_messages/get_message_status in client.py; MessageType/MessageData in types.py
1-5 CLI commands VERIFIED egg-orch message send/poll/status in orch_cli.py with JSON output
1-6 Integration tests DEVIATION Tests exist in test_concurrent_integration.py (message send/poll/broadcast), but specified files test_message_store.py and test_message_api.py do not exist. Coverage is adequate via integration tests.

Phase 2: Concurrent Phase Executor

Task Status Notes
2-1 PipelineConfig fields VERIFIED All 5 config fields present with correct types and defaults
2-2 ConcurrentPhaseExecutor VERIFIED Full implementation: spawn_all with ThreadPoolExecutor, per-agent worktree branches, single failure HITL (retry/abort/continue), multiple failure abort (2+ within 60s)
2-3 Container spawner changes BLOCKING orchestrator/container_spawner.py is NOT modified in this PR. Task requires adding support for concurrent multi-agent spawn with per-agent worktree branches and messaging env vars. ConcurrentPhaseExecutor assumes spawn_fn accepts branch and extra_env, but container_spawner.py doesn't accept these params.
2-4 Execution routing BLOCKING is_concurrent_execution() helper added to multi_agent.py but is never called anywhere. No code routes phase execution to ConcurrentPhaseExecutor when concurrent_execution=true. Status monitoring in pipelines.py works, but actual execution path is not wired. The feature cannot be triggered end-to-end.
2-5 Executor tests DEVIATION Tests exist across test_concurrent_integration.py and test_concurrent_status.py, but specified file test_concurrent_executor.py does not exist. Core scenarios covered (spawn, single/multi failure, consensus).

Phase 3: Consensus Protocol

Task Status Notes
3-1 ReadinessState + AgentReadiness VERIFIED Enum with WORKING/READY/BLOCKED/OBJECTING and Pydantic model in models.py
3-2 ConsensusEvaluator VERIFIED Thread-safe singleton with register/update/evaluate/remove/clear. Objection handling works.
3-3 Readiness signal handler VERIFIED Handler in signals.py with state validation and EventBus events
3-4 Client + CLI VERIFIED signal_readiness in client.py; egg-orch signal readiness command with state/reason args
3-5 Executor integration VERIFIED ConcurrentPhaseExecutor registers agents in consensus evaluator, check_consensus() delegates to evaluator
3-6 Integration tests DEVIATION Tests in test_concurrent_integration.py cover all-ready, objection-blocks, ready-to-working, blocked-prevents. No dedicated test_consensus.py file, but scenarios are covered.

Phase 4: Agent Prompts and Integration Testing

Task Status Notes
4-1 Agent prompts VERIFIED mission.md has comprehensive concurrent mode section (polling, readiness signaling, per-role collaboration patterns, failure handling)
4-2 Checkpoint capture VERIFIED _fetch_inter_agent_messages() in checkpoint_handler.py with graceful degradation; 19 dedicated tests pass
4-3 Status monitoring VERIFIED _get_concurrent_status() returns messages/consensus/agents in pipeline status endpoint; 12 dedicated tests pass
4-4 End-to-end integration test VERIFIED test_concurrent_integration.py covers full lifecycle (status, messages, consensus, failures) with 11 tests
4-5 Documentation VERIFIED sdlc-pipeline.md covers config, protocol, agent behavior, worktrees, failure handling, monitoring, troubleshooting

Blocking Issues

  1. Task 2-3: container_spawner.py not modified. The contract specifies modifying orchestrator/container_spawner.py to support concurrent multi-agent spawn with per-agent worktree branches and messaging env vars. The file has zero changes in this PR. ConcurrentPhaseExecutor.spawn_all() passes branch and extra_env to spawn_fn, but the actual spawn_agent_container method doesn't accept these parameters. This means ConcurrentPhaseExecutor cannot function against the real container spawner.

  2. Task 2-4: Execution routing not wired. is_concurrent_execution() is defined but never imported or called. No code path delegates to ConcurrentPhaseExecutor when concurrent_execution=true. The concurrent executor exists as dead code — it cannot be triggered by any pipeline. This is the critical integration point that connects all other Phase 1-3 work to actual execution.

Non-Blocking Deviations

  1. Tasks 1-6, 2-5, 3-6: Test file organization. Contract specifies test_message_store.py, test_message_api.py, test_concurrent_executor.py, and test_consensus.py as separate files. These do not exist; tests are consolidated in test_concurrent_integration.py and test_concurrent_status.py. Functionally adequate but doesn't match contract file layout.

Contract Metadata

  • All 22 tasks have status: "pending" — none marked complete despite implementation existing
  • All 5 HITL decisions are unresolved (this is expected for contract questions vs implementation)
  • No acceptance_criteria at top level (empty list)
  • No commits linked to any tasks

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

No agent-mode design concerns.

The design aligns well with agent-mode principles:

  • Polling-based messaging fits Claude Code's request-response model — agents pull messages via egg-orch message poll when they choose, rather than receiving pushed data
  • Hybrid message format (structured envelope for routing, free-form body for content) gives the orchestrator routing metadata without constraining agent communication
  • Consensus protocol is infrastructure-enforced, not prompt-enforced — agents signal readiness via CLI, and the orchestrator evaluates consensus server-side
  • No pre-fetching: messages aren't baked into agent prompts; agents discover them via tool calls
  • No direct LLM API calls, no hardcoded model identifiers, no post-processing pipelines

The role-specific collaboration patterns in mission.md are prescriptive, but they orient agents on how to use an entirely new communication mechanism — this is "information the agent can't easily discover" rather than micromanagement of existing capabilities.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

- Validate limit param and pipeline existence in poll_messages/message_status
- Add READINESS_CHANGED event type instead of reusing AGENT_STARTED/COMPLETED
- Wire message store and consensus clear() into phase transitions
- Narrow exception handling in _get_concurrent_status to ImportError only
- Fix agent role serialization to use .value for enum types
- Add create_concurrent_spawn_fn to ContainerSpawner for concurrent mode
- Wire is_concurrent_execution() into _run_pipeline execution routing
- Fix TokenUsage field name: cache_write_tokens -> cache_creation_tokens
Copy link
Contributor Author

@james-in-a-box james-in-a-box bot left a comment

Choose a reason for hiding this comment

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

Review Feedback Addressed

All 5 blocking issues and 4 non-blocking issues from the code review and contract verification have been addressed in commit 3a8950a.

Blocking Issues Fixed

1. poll_messages unvalidated limit parameter — Added try/except (ValueError, TypeError) around int() conversion with a 400 error response.

2. poll_messages and message_status skip pipeline validation — Both GET endpoints now validate pipeline existence via get_state_store().load_pipeline(), matching the POST endpoint pattern. Returns 404 for invalid/nonexistent pipeline IDs with InvalidPipelineIdError protection.

3. handle_readiness_signal emits misleading event types — Added new EventType.READINESS_CHANGED = "readiness.changed" and replaced the AGENT_COMPLETED/AGENT_STARTED reuse with it. SSE consumers tracking container lifecycle will no longer receive false signals.

4. Messages never cleared on phase transitions — Added _clear_concurrent_state() helper that calls get_message_store().clear() and get_consensus_evaluator().clear(). Wired into all three phase transition endpoints: advance_phase(), complete_phase(), and fail_phase().

5. _get_concurrent_status broad exception handling — Changed from except (ImportError, Exception) to structured try/except ImportError for the import only, letting runtime errors from get_message_store() and get_consensus_evaluator() propagate.

Contract Blocking Issues Fixed

Task 2-3: container_spawner.py — Added create_concurrent_spawn_fn() method that returns a callable matching ConcurrentPhaseExecutor's expected signature (role, branch, extra_env), wrapping spawn_agent_container with pre-bound pipeline config.

Task 2-4: Execution routingis_concurrent_execution() is now called in _run_pipeline() to check pipeline.config.concurrent_execution. When true, routes to new _run_concurrent_phase() which instantiates ConcurrentPhaseExecutor with the spawn fn from the container spawner.

Additional Fixes

  • TokenUsage field name (#10): Fixed cache_write_tokenscache_creation_tokens in test to match model definition.
  • Agent role serialization (#13): Fixed to use agent.role.value for enum serialization while preserving hasattr guards for mocks.

Not Addressed (Disagreements / By Design)

  • #6 Truncated UUID: For the expected message volume (tens per phase, cleared on transition), 64 bits of randomness is sufficient. Switching to sequential integers would require additional synchronization. Will revisit if message volume increases.
  • #7 O(n) since_id scan: Acceptable for expected volumes as noted in the review.
  • #8 Copy under lock: Acceptable eventual consistency for polling model as noted.
  • #9 Self-sent broadcasts: This is inherent to broadcast semantics. The checkpoint handler already classifies direction correctly. Documented behavior.
  • #11 Mock-based integration tests: Test file organization is a non-blocking deviation acknowledged by both reviewers. The existing tests cover all core scenarios.
  • #12 Duplicate type definitions: Added as a known trade-off. The orchestrator runs as a standalone process and can't always import from shared at startup.
  • #14 Hardcoded agent roles: Intentional for V1 — integrator joins after consensus. Will evolve with dispatch integration.

All 69 tests pass, lint clean.

— Authored by egg

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

No agent-mode design concerns in the delta.

All changes since my last review are correctness fixes (input validation, event type semantics, exception handling) and infrastructure wiring (concurrent spawn fn, execution routing, phase-transition cleanup). The core agent-mode design is unchanged:

  • Agents still discover messages via polling (egg-orch message poll), not pre-fetching
  • Consensus remains infrastructure-enforced server-side
  • No new prompt-level constraints, no direct LLM API calls, no hardcoded model IDs

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor Author

@james-in-a-box james-in-a-box bot left a comment

Choose a reason for hiding this comment

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

Contract Re-Verification: PR #1031 (Incremental)

Previous review: commit 04ac381
Current review: commit 3a8950a

Delta Summary

One commit since last review: "Address review feedback on cross-agent messaging PR" — 7 files changed, 237 insertions, 14 deletions.

Review Feedback Verification

All 8 items from the code review are correctly addressed:

# Feedback Item Status Files
1 Validate limit param and pipeline existence in poll/status Correct routes/messages.py
2 Add READINESS_CHANGED event type Correct events.py, routes/signals.py
3 Wire message store + consensus clear() into phase transitions Correct routes/phases.py
4 Narrow exception handling to ImportError only Correct routes/pipelines.py
5 Fix agent role serialization to use .value Correct routes/pipelines.py
6 Add create_concurrent_spawn_fn to ContainerSpawner Correct container_spawner.py
7 Wire is_concurrent_execution() into _run_pipeline Correct routes/pipelines.py
8 Fix TokenUsage field: cache_write_tokens → cache_creation_tokens Correct test_checkpoint_cli_inter_agent.py

Test Results

All tests pass:

  • 8/8 checkpoint CLI inter-agent tests
  • 26/26 concurrent/message/consensus tests
  • 69/69 event-related tests
  • 4/4 multi-agent tests

Remaining Issue (Non-blocking)

container_id extraction bug in concurrent_executor.py:156:

container_id=getattr(result, "container_id", None),  # Always None

SpawnedContainer doesn't have a direct container_id attribute — it's nested at result.container_info.container_id. Now that create_concurrent_spawn_fn is wired up (returning SpawnedContainer), this means AgentExecution.container_id will always be None for concurrently-spawned agents. This affects health check monitoring and startup reconciliation but won't cause crashes.

Fix: Either getattr(getattr(result, 'container_info', None), 'container_id', None) or add a container_id property to SpawnedContainer.

Contract Status

The contract's top-level acceptance_criteria array is empty — no criteria to mark with verify-criterion. All per-task implementations are present in the codebase with passing tests. Task commit linkage was not performed during implementation (all tasks show "pending" status), which is a process gap but not a contract violation.

No Regressions

Previously verified behavior is intact. The review feedback changes are additive (new validations, new routing, new event type) and don't break any existing functionality.

Verdict

Approve with note. All review feedback is correctly implemented. The container_id extraction bug should be fixed in a follow-up but is non-blocking for merge — concurrent execution is opt-in (default false) and the missing tracking data only affects monitoring, not correctness.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

Re-review: Cross-agent messaging and concurrent phase execution

Previous review at 04ac381. This review covers commit 3a8950a which addressed feedback.

Previous Feedback Verification

Properly fixed:

  • #1 poll_messages limit validation — try/except (ValueError, TypeError) correctly added
  • #2 Pipeline validation on GET endpoints — both poll_messages and message_status now validate via load_pipeline() with proper 404 handling
  • #3 READINESS_CHANGED event type — new EventType.READINESS_CHANGED = "readiness.changed" added and used correctly
  • #4 Message/consensus clearing on phase transitions — _clear_concurrent_state() wired into advance_phase(), complete_phase(), and fail_phase(), all after the save_pipeline() call succeeds
  • #5 Narrow exception handling in _get_concurrent_status — changed to except ImportError only
  • #10 cache_write_tokenscache_creation_tokens — fixed in test, matches model
  • #13 Agent role serialization — agent.role.value used correctly
  • Contract 2-3 create_concurrent_spawn_fn() — properly implemented, correct signature, environment merging works

Not fully resolved:

  • Contract 2-4 Execution routing — see blocking issue #1 below

Blocking Issues

1. _run_concurrent_phase is fire-and-forget — the concurrent execution feature is non-functional end-to-end
orchestrator/routes/pipelines.py:4415-4467

_run_concurrent_phase() spawns all agent containers via executor.spawn_all() and returns immediately. It does not:

  • Wait for agents to complete. spawn_all() calls spawn_agent_container() which starts Docker containers and returns. There is no docker_client.wait_for_container() call anywhere in the concurrent path. Compare with _spawn_and_wait() (line 4565) which correctly blocks on wait_for_container().
  • Pass a command or prompt. create_concurrent_spawn_fn._spawn() calls spawn_agent_container() without a command parameter. The sequential path builds a sandbox_command (["claude", "--print", ..., prompt_text]) and passes it to _spawn_and_wait. Concurrent containers start with the image's default CMD and no phase-specific prompt.
  • Wait for consensus. The ConcurrentPhaseExecutor has check_consensus() but _run_concurrent_phase never calls it.

The result: _run_concurrent_phase returns (0, logs) when all spawns succeed, the pipeline loop at line 6071 sees exit_code == 0, and proceeds to run check-and-fix (line 6099) and eventually advance the phase — while agents haven't even started their actual work.

Compare the three execution paths:

Path Spawns Waits Has prompt Records state
_spawn_and_wait (sequential) wait_for_container sandbox_command ✓ containers + agents
_run_multi_agent_phase (wave) ✓ wraps _spawn_and_wait _build_agent_prompt ✓ via _spawn_and_wait
_run_concurrent_phase (concurrent)

The routing fix (contract 2-4) makes _run_concurrent_phase callable, but the function itself is incomplete. This needs at minimum: prompt generation per-role, passing the command to spawn_agent_container, waiting for all containers to exit (or polling for consensus then waiting), and recording containers/agents in pipeline state.

2. container_id always None in concurrent agent executions
orchestrator/concurrent_executor.py:156

container_id=getattr(result, "container_id", None),

result is a SpawnedContainer, which has container_info: ContainerInfo, not a direct container_id attribute. ContainerInfo.container_id is the actual field (models.py:133). This getattr always returns None.

Should be:

container_id=result.container_info.container_id,

This breaks any downstream code that needs to track, monitor, or clean up concurrent agent containers by ID.


Non-Blocking Issues

3. handle_readiness_signal has no exception handling
orchestrator/routes/signals.py:616-658

Lines 616-658 (consensus operations, event emission, evaluation) are not wrapped in try/except. Every other signal handler in this file (handle_complete_signal, handle_error_signal, handle_progress_signal) wraps its core operations in structured exception handling with specific catches for InvalidPipelineIdError, PipelineNotFoundError, ContractNotFoundError, and a general Exception fallback.

If evaluator.update_readiness() or evaluator.evaluate() throws (e.g., due to a corrupted consensus state or an unexpected enum value), the endpoint returns a raw 500 with no structured error response and no logging. Add exception handling consistent with the other signal handlers.

4. Concurrent agents not recorded in pipeline state store
orchestrator/routes/pipelines.py:4459

_spawn_and_wait() (lines 4526-4561) records each spawned container and agent execution in the pipeline state via phase_execution.containers.append(...) and phase_execution.agents.append(...). This makes them visible in the pipeline status endpoint.

_run_concurrent_phase() does not record anything in the state store. Concurrent agents will be invisible to the status endpoint's container/agent lists. The _get_concurrent_status() helper partially compensates via the consensus evaluator, but containers are not tracked.

— Authored by egg

@james-in-a-box
Copy link
Contributor Author

Review Feedback Addressed (Round 2)

All 4 issues from the second review have been addressed in commit d208f0a.

Blocking Issues Fixed

1. _run_concurrent_phase is fire-and-forget — now fully functional

The function now mirrors the _run_multi_agent_phase pattern:

  • Prompt generation: Builds per-role prompts via _build_agent_prompt() for coder, tester, and documenter roles.
  • Command passing: Prompts flow through spawn_all(agent_prompts=...)_spawn_agent() which builds the claude --print sandbox command and passes it to spawn_fn(command=...). The create_concurrent_spawn_fn inner function now accepts and forwards a command parameter to spawn_agent_container.
  • Container waiting: After spawning, uses a ThreadPoolExecutor to concurrently wait for all containers via docker_client.wait_for_container() with a 3600s timeout. Handles ContainerNotFoundError and ContainerOperationError gracefully.
  • State recording: Records containers and agent executions in the pipeline state store both at spawn time and after completion, matching the _spawn_and_wait pattern. Status endpoint can now track concurrent agents.

2. container_id always None

Changed from getattr(result, "container_id", None) to result.container_info.container_id in concurrent_executor.py:_spawn_agent(), correctly accessing the nested SpawnedContainer field.

Non-Blocking Issues Fixed

3. handle_readiness_signal exception handling

Added structured exception handling consistent with handle_complete_signal and other signal handlers:

  • Pipeline existence validation via get_state_store().load_pipeline() before processing
  • InvalidPipelineIdError → 400
  • PipelineNotFoundError → 404
  • General Exception fallback → 500 with logging

4. Concurrent agents not recorded in pipeline state store

_run_concurrent_phase now records all spawned containers and agent executions in the phase execution state, and updates their status (COMPLETE/FAILED) after each container exits. This makes concurrent agents visible to the status endpoint's container/agent lists.

All 7503 tests pass, lint clean.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

No agent-mode design concerns in the delta.

The changes since my last review (commit 3a8950a) are correctness and completeness fixes — making _run_concurrent_phase fully functional, fixing container_id access, adding exception handling to the readiness signal handler, and recording concurrent agents in pipeline state. None of these change the agent-mode design:

  • Prompt generation: _run_concurrent_phase delegates to _build_agent_prompt() — the same function used by sequential/wave paths. No pre-fetched diffs or large content embedded.
  • Model selection: Uses --model opus (short alias), consistent with all other spawn paths in pipelines.py and compliant with EGG201.
  • No new prompt constraints, no direct LLM API calls, no post-processing pipelines.
  • Consensus and messaging remain infrastructure-enforced and polling-based.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor Author

@james-in-a-box james-in-a-box bot left a comment

Choose a reason for hiding this comment

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

Contract Re-Verification: PR #1031 (Incremental — Round 3)

Previous review: commit 3a8950ad90f49b566a3daa6baf276ef626b20892
Current review: commit d208f0a5e80c9ee15df8a1356a179514982d8f4f

Delta Summary

One commit since last review: "Address second round of review feedback on concurrent execution" — 4 files changed (concurrent_executor.py, container_spawner.py, routes/pipelines.py, routes/signals.py).

Review Feedback Verification

All 4 issues from the second code review (egg-reviewer[bot]) are addressed:

# Issue Severity Status Verification
1 _run_concurrent_phase fire-and-forget — no wait, no prompts, no state recording Blocking Fixed Now builds per-role prompts via _build_agent_prompt, passes them to spawn_all(agent_prompts=...), waits for all containers via ThreadPoolExecutor + docker_client.wait_for_container(timeout=3600), records container/agent state in pipeline store
2 container_id always None due to getattr(result, "container_id", None) Blocking Fixed Changed to result.container_info.container_id in concurrent_executor.py:190
3 handle_readiness_signal no exception handling Non-blocking Fixed Added pipeline existence validation (InvalidPipelineIdError → 400, PipelineNotFoundError → 404), wrapped consensus operations in try/except with structured 500 error response and logging
4 Concurrent agents not recorded in pipeline state Non-blocking Fixed _run_concurrent_phase now records ContainerInfo and AgentExecution in phase_execution after spawning, and updates status after each container exits

Detailed Verification

_run_concurrent_phase (pipelines.py) — Previously returned immediately after spawning. Now:

  1. Builds per-role prompts for CODER, TESTER, DOCUMENTER using _build_agent_prompt()
  2. Passes prompts to executor.spawn_all(agent_prompts=agent_prompts)
  3. Records containers and agents in pipeline state store (with error tolerance)
  4. Checks for spawn failures and fails fast
  5. Waits for all containers concurrently via _wait_and_record() using ThreadPoolExecutor
  6. Updates final container/agent status in pipeline state after exit
  7. Returns (1, logs) on any failure, (0, logs) on success

This matches the execution pattern of the sequential (_spawn_and_wait) and wave (_run_multi_agent_phase) paths.

_spawn_agent (concurrent_executor.py) — Now accepts prompt_text parameter and builds a Claude CLI command: ["claude", "--dangerously-skip-permissions", "--print", "--verbose", "--output-format", "stream-json", "--model", "opus", "--max-turns", "200", prompt_text]. Command is passed through spawn_fn(command=command).

_spawn closure (container_spawner.py) — Inner function now accepts and forwards command: list[str] | None = None to spawn_agent_container(). Confirmed spawn_agent_container accepts this parameter in its signature.

handle_readiness_signal (signals.py) — Now consistent with other signal handlers: validates pipeline existence before processing, structured exception handling around consensus operations, proper HTTP status codes.

Test Results

All 69 tests pass (unchanged from previous review):

  • test_concurrent_integration.py — 11 passed
  • test_concurrent_status.py — 12 passed
  • test_checkpoint_inter_agent.py — 19 passed
  • test_checkpoint_cli_inter_agent.py — 8 passed
  • test_events.py — 15 passed
  • test_multi_agent.py — 4 passed

Lint clean (ruff check passes on all 4 changed files).

No Regressions

Previously verified contract tasks remain intact:

  • Phase 1 (Message API): All 6 tasks verified — no changes in this delta
  • Phase 2 (Concurrent Executor): All 5 tasks now verified — blocking gaps (2-3 container_spawner, 2-4 execution routing) resolved in prior commit, now fully functional with prompt passing and container waiting
  • Phase 3 (Consensus Protocol): All 6 tasks verified — readiness signal handler now has proper error handling
  • Phase 4 (Agent Prompts/Integration): All 5 tasks verified — no changes in this delta

Contract Metadata

The contract's top-level acceptance_criteria array is empty — no criteria to mark with verify-criterion. Per-task acceptance criteria are verified through code review and test execution.

Verdict

Approve. All blocking issues from the second code review are resolved. The concurrent execution path is now functionally complete: prompts are generated, containers are spawned with commands, the orchestrator waits for completion, and state is tracked throughout. No regressions detected.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

Re-review: Cross-agent messaging and concurrent phase execution (round 3)

Previous review at 3a8950a. This review covers commit d208f0a which addresses the second round of feedback.

Previous Feedback Verification

All 4 issues from the previous review are properly fixed:

Blocking #1 (fire-and-forget _run_concurrent_phase)Fixed correctly. The function now:

  • Builds per-role prompts via _build_agent_prompt (matching the multi-agent wave pattern)
  • Passes prompts through spawn_all()_spawn_agent() which constructs the Claude CLI command
  • Passes the command through the spawn function to spawn_agent_container
  • Waits for all containers to exit via docker_client.wait_for_container() using a ThreadPoolExecutor
  • Returns (exit_code, logs) based on actual container exit codes

The wait pattern correctly mirrors _spawn_and_wait (the sequential path), with appropriate error handling for ContainerNotFoundError and ContainerOperationError.

Blocking #2 (container_id always None)Fixed correctly. Changed from getattr(result, "container_id", None) to result.container_info.container_id, which properly accesses the nested SpawnedContainer.container_info.container_id field.

Non-blocking #3 (handle_readiness_signal exception handling)Fixed correctly. Pipeline existence is now validated via store.load_pipeline() with specific catches for InvalidPipelineIdError (400) and PipelineNotFoundError (404). The consensus operations are wrapped in a separate try/except Exception block with structured error logging and a 500 response. This is consistent with the other signal handlers.

Non-blocking #4 (concurrent agents not recorded in pipeline state)Fixed correctly. Containers and agents are recorded in PhaseExecution immediately after spawning (lines 4501-4535), then updated on container exit with final status, exit code, and timestamps (lines 4590-4620). Both operations use get_pipeline_state_lock for thread safety.


New Non-Blocking Issues

1. Partial spawn failure orphans running containers
orchestrator/routes/pipelines.py:4537-4543

If 1 of 3 agents fails to spawn, the function returns (1, logs) immediately without stopping the containers that spawned successfully. Those containers continue running — consuming compute, potentially pushing commits, and writing to branches in a phase already marked as failed.

Suggestion: stop running containers before returning on partial failure:

if spawn_failures:
    for e in executions:
        if e.container_id and e.status.value != "failed":
            try:
                spawner.docker.stop_container(e.container_id, timeout=10)
            except Exception:
                pass
    logs = "\n".join(...)
    return 1, logs

2. Executor failure handling and consensus methods are unused

_run_concurrent_phase uses ConcurrentPhaseExecutor only for spawn_all(). The executor's handle_agent_failure(), check_consensus(), and _abort_phase() methods are never called. The function implements its own simpler "wait for exit codes" pattern instead of integrating the consensus-driven phase advancement that the executor was designed for.

This means the consensus protocol (agents signaling READY/BLOCKED/OBJECTING via the readiness endpoint) has no effect on orchestrator-side phase advancement — it's purely agent-to-agent communication. The phase completes when all containers exit, regardless of consensus state.

This is acceptable for V1, but worth a comment in _run_concurrent_phase explaining that consensus integration is deferred, so someone reading the code understands why check_consensus() exists but isn't called.

3. No tests for the new wait/state-tracking logic

The commit adds ~170 lines of concurrent wait and pipeline state tracking logic (the _wait_and_record closure, ThreadPoolExecutor orchestration, partial failure handling) with no new tests. The existing test suite covers spawn and status, but not the container wait lifecycle or state updates.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box
Copy link
Contributor Author

Review Feedback Addressed (Round 3)

All 3 non-blocking suggestions from the third review have been addressed in commit 743932e.

Changes

1. Partial spawn failure stops orphaned containers — When spawn_failures is non-empty, _run_concurrent_phase now iterates over successfully-spawned executions and calls spawner.docker.stop_container() before returning (1, logs). Exceptions from stop_container are caught and swallowed so the cleanup doesn't block the failure return.

2. Consensus integration deferred — comment added — Added an explanatory comment in _run_concurrent_phase before the wait loop explaining that ConcurrentPhaseExecutor.check_consensus() and handle_agent_failure() exist but are not called in V1. Phase completion is determined by container exit codes. Consensus-driven advancement will be integrated in a follow-up.

3. Tests for wait/state-tracking logic — Added test_concurrent_wait.py with 8 tests covering:

  • All containers exit successfully → (0, logs)
  • Container failure → (1, logs) with role name in logs
  • ContainerNotFoundError during wait → failure path
  • Pipeline state store records containers and agents (save_pipeline called ≥2 times)
  • store=None graceful degradation
  • Partial spawn failure stops running containers (verifies stop_container called for each)
  • stop_container error doesn't block failure return
  • All spawns fail → no stop_container calls

All 50 concurrent/event/multi-agent tests pass. Lint clean.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box
Copy link
Contributor Author

Autofix tracking
{"Lint/Python": 1}

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

No agent-mode design concerns in the delta.

Changes since d208f0a are a container cleanup fix (stopping orphaned containers on partial spawn failure) and a new test file for wait/cleanup logic. No prompt changes, no pre-fetching, no direct API calls — purely operational correctness.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor Author

@james-in-a-box james-in-a-box bot left a comment

Choose a reason for hiding this comment

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

Contract Re-Verification: PR #1031 (Incremental — Round 4)

Previous review: commit d208f0a5e80c9ee15df8a1356a179514982d8f4f
Current review: commit 7c191cd8ae5ceda11b412cc5bfda1b24fb1fc487

Delta Summary

Two commits since last review:

  • 743932e — "Address round 3 review suggestions on concurrent execution"
  • 7c191cd — "Fix checks: apply automated formatting fixes"

Files changed: orchestrator/routes/pipelines.py (modified), orchestrator/tests/test_concurrent_wait.py (added).

Round 3 Suggestion Verification

All 3 non-blocking suggestions from the round 3 code review are addressed:

# Suggestion Status Verification
1 Partial spawn failure orphans running containers Fixed Containers that spawned successfully are now stopped before returning on partial failure. Errors from stop_container are swallowed to avoid blocking the failure return path.
2 Consensus methods unused — add explanatory comment Fixed NOTE comment added at the wait loop explaining that V1 uses container exit codes for phase completion, with consensus-driven advancement deferred to a follow-up.
3 No tests for wait/state-tracking logic Fixed New test_concurrent_wait.py with 8 tests in 2 classes covering: successful exit, container failure, container-not-found, state recording, store=None tolerance, partial spawn cleanup, stop-error tolerance, all-spawns-fail.

Code Review of Delta

Container cleanup on partial spawn failure (pipelines.py:4537-4545): Iterates over executions, stops containers that have a container_id and aren't already failed. Uses timeout=10 for stop. Swallows exceptions from stop_container — correct, since failure to stop a container shouldn't prevent the error return.

NOTE comment (pipelines.py:4548-4554): Clearly explains the V1 approach (container exit codes) vs the future approach (consensus-driven advancement). References check_consensus() and handle_agent_failure() methods on the executor.

Test file (test_concurrent_wait.py): Well-structured with proper mocking. Tests verify exit codes, wait call counts, state store interactions, stop_container calls on partial failure, and error tolerance. All tests are isolated and deterministic.

Test Results

  • 8 new tests in test_concurrent_wait.py — all pass
  • 1634 total orchestrator tests — all pass
  • Lint clean (ruff check passes on both files)

No Regressions

Previously verified contract tasks remain intact. The delta only adds cleanup behavior and tests — no changes to message API, consensus protocol, agent prompts, or integration tests.

Contract Metadata

The contract's top-level acceptance_criteria array is empty — no criteria to mark with verify-criterion. Per-task acceptance criteria are verified through code review and test execution (see round 3 verification for full task-by-task analysis).

Verdict

Approve. All non-blocking suggestions from round 3 are addressed. The concurrent execution path now has proper partial-failure cleanup and comprehensive test coverage for the wait/state-tracking lifecycle. No regressions. All 1634 tests pass.

— Authored by egg

@james-in-a-box

This comment has been minimized.

Copy link
Contributor

@egg-reviewer egg-reviewer bot left a comment

Choose a reason for hiding this comment

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

Re-review: Cross-agent messaging and concurrent phase execution (round 4)

Previous review at d208f0a. This review covers the delta to HEAD (7c191cd): two commits addressing round 3 feedback and automated formatting fixes.

Previous Feedback Verification

All 3 non-blocking suggestions from my round 3 review are properly addressed:

#1 (Partial spawn failure orphans running containers)Fixed correctly.
orchestrator/routes/pipelines.py:4537-4550

When spawn_failures is non-empty, the function iterates over all executions and calls spawner.docker.stop_container() on those with a container ID and non-failed status. Exceptions from stop_container are swallowed so cleanup doesn't block the failure return. The logic correctly handles:

  • Filtering: e.container_id and e.status.value != "failed" — only stops containers that actually started
  • Edge case: all spawns fail → spawn_failures == executions, no containers to stop (tested)
  • Error tolerance: except Exception: pass is appropriate for best-effort cleanup

#2 (Consensus integration comment)Added correctly.
orchestrator/routes/pipelines.py:4552-4560

Clear explanatory comment documenting that ConcurrentPhaseExecutor.check_consensus() and handle_agent_failure() exist but are intentionally unused in V1. Phase completion uses container exit codes, matching the sequential/wave paths.

#3 (No tests for wait/state-tracking logic)Added correctly.
orchestrator/tests/test_concurrent_wait.py — 8 tests covering:

  • All containers exit successfully → (0, logs)
  • Container failure → (1, logs) with role in logs ✓
  • ContainerNotFoundError during wait → failure path ✓
  • Pipeline state store records containers/agents (save_pipeline called ≥2 times) ✓
  • store=None graceful degradation ✓
  • Partial spawn failure stops running containers ✓
  • stop_container error doesn't block failure return ✓
  • All spawns fail → no stop_container calls ✓

New Code Review

Examined the partial spawn cleanup logic, test file, and formatting changes. No issues found.

The cleanup at lines 4537-4550 is correctly positioned after spawn recording (lines 4501-4535) but before the wait loop (lines 4561-4653). The ThreadPoolExecutor usage is correct — each _wait_and_record closure acquires the pipeline state lock independently, and the spawn recording lock is released before any closures start.

Test Results

All 77 tests pass:

  • test_concurrent_wait.py — 8 passed
  • test_concurrent_integration.py — 11 passed
  • test_concurrent_status.py — 12 passed
  • test_checkpoint_inter_agent.py — 19 passed
  • test_checkpoint_cli_inter_agent.py — 8 passed
  • test_events.py — 15 passed
  • test_multi_agent.py — 4 passed

Verdict

No blocking issues remain. All feedback from 3 rounds of review has been addressed. The concurrent execution path is functionally complete: prompts are generated, containers are spawned with commands, the orchestrator waits for completion, state is tracked, and orphaned containers are cleaned up on partial failure.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box
Copy link
Contributor Author

egg is addressing review feedback...

@james-in-a-box
Copy link
Contributor Author

All review feedback from 4 rounds has been addressed. Latest review (round 4) confirms all issues resolved — no new blocking or non-blocking items.

Current state: 31 concurrent/status/integration tests pass, lint clean.

— Authored by egg

@james-in-a-box
Copy link
Contributor Author

egg feedback addressed. View run logs

19 previous review(s) hidden.

@jwbron jwbron merged commit be1de7f into main Mar 11, 2026
36 checks passed
github-actions bot pushed a commit that referenced this pull request Mar 11, 2026
Update documentation to reflect changes from be1de7f:
- Add concurrent_executor.py, consensus.py, message_store.py to
  STRUCTURE.md orchestrator module listing
- Add routes/messages.py to routes listing; annotate signals.py with
  readiness signal support
- Add message bus API endpoints to orchestrator architecture doc
- Update signal endpoint description to include readiness signal type

Triggered by: #1031 (Add cross-agent messaging and concurrent phase execution)

Authored-by: egg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable cross-agent communication and concurrent phase execution

1 participant