Skip to content

Verification pool sessions share one executor, violating the "separate sessions" invariant #5

Description

@callumee

Verification pool sessions share one executor, violating the "separate sessions" invariant

Severity: High
File: src/cain_agent/multi_agent/orchestration.py:91-93

build_orchestration creates multiple ExecutorVerificationSession instances but they all wrap the same validation_executor object:

sessions = tuple(
    ExecutorVerificationSession(f"verify-{index}", validation_executor)
    for index in range(session_count)
)

The architecture requires independent verification sessions for majority-vote integrity (FindingsPipeline.__init__ explicitly rejects pool sessions that share the discovery executor). Yet all three verification sessions share a single SDKExecutor, meaning they share the same hooks, allowed_tools, and — critically — the same underlying Claude Agent SDK session when resume_session_id is set. The pool then runs asyncio.run() per call inside ThreadPoolExecutor threads, but all threads drive the same executor state.

Why it matters

If one verification thread mutates executor state (e.g., appending a hook, advancing a session), the other threads observe the mutation. A failure in one session could corrupt the shared state for all three, turning an independent majority vote into a correlated single-point result — undermining the anti-self-certification design.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions