Skip to main content
Subscribe

Conductor Adaptive Graphs: Governed PR Reviews at Scale

Build governed Conductor adaptive graphs that review pull requests with bounded fan-out, durable evidence passes, and human approval before posting.

Deepak Bagada

Deepak Bagada

Founder & Editor-in-Chief

Sep 18, 2026 Published
|
Sep 18, 2026 Updated
|
8 Minutes Reading Time
Core Takeaways for Founders & Builders
  • Four durable evidence passes plus HUMAN gate produced zero unapproved posts across 140 PRs
  • Bounded fan-out at 2 caps p99 cost at $0.31 versus $14 unbounded
  • Ledger synthesis cuts per-review tokens 74% to $0.11 with 2.1s median pass latency

Conductor Adaptive Graphs: Governed PR Reviews at Scale

Conductor durable adaptive graphs let an agent choose its next steps at runtime while every choice stays validated, persisted, and gated by approval. The flagship pattern is a governed GitHub PR reviewer: four durable evidence passes, bounded parallel deep-dives, then one human approval before a single comment posts.

  • Four evidence passes persist as workflow variables, not chat history
  • Bounded fan-out caps parallel reads at two approved paths
  • HUMAN task blocks the single side effect until approval lands

I deployed this exact graph at SaaSNext last week on Conductor OSS 3.32. It reviewed 140 pull requests without posting a single unapproved comment. Getting there exposed two failure modes the docs gloss over.

The problem with free-running review agents

A plain think-act agent reviewing PRs has one dangerous property: the model output is the command. It decides to post, and the post happens. No schema check. No policy gate. No audit trail beyond a log line.

We ran that version in June. It posted a review comment containing an internal staging URL to a public fork. No malice. Just a model guessing a link. Cleanup took a day. Legal asked questions. That ended free-running reviewers for us.

Conductor flips the contract. Model output is a proposal. The graph validates it, applies policy, and only then schedules work. The agent behind the boundary can be native tasks, a compiled framework agent, or a remote A2A service. The parent workflow owns the business process either way.

This is the same durability argument I made for sandbox agents that survive crashes: state belongs in the engine, not in process memory. Conductor applies it to the whole review pipeline.

How the governed graph works

The runnable reference is ai/examples/35-governed-adaptive-agent.json in the Conductor repo. It uses built-in tasks only, so you need zero custom workers to start.

graph TD
  A[Read PR context + intent] --> B[Inspect changed-file surface]
  B --> C[Inspect CI check runs]
  C --> D[Choose 1-2 deep dives]
  D -->|bounded fork| E[Diff read]
  D -->|bounded fork| F[Reviews + comments read]
  E --> G[Synthesize from ledger]
  F --> G
  G --> H{HUMAN approval}
  H -->|approved| I[Post single comment]
  H -->|rejected| J[End, no side effect]

Each pass writes a compact validated assessment into a workflow variable. The final comment synthesizes from that durable ledger. Unbounded chat history never touches the posting step.

Pass 1 reads PR context and intent. Pass 2 inspects the changed-file surface. Pass 3 inspects CI check runs. Pass 4 uses the first three persisted assessments to choose one or two approved deep-dive reads and runs them in bounded parallel through FORK_JOIN_DYNAMIC.

Task inventory is small and explicit: LIST_MCP_TOOLS, CALL_MCP_TOOL, LLM_CHAT_COMPLETE, JSON_JQ_TRANSFORM, FORK_JOIN_DYNAMIC, JOIN, HUMAN, SWITCH, SET_VARIABLE, DO_WHILE. If the model requests a tool outside the allowlist, the call never schedules. The model gets told what it can actually use.

Teams running durable multi-agent graphs in Go will recognize the ledger-first shape. Same principle: persist evidence, then decide.

Step 1: Server setup and registration

You need Conductor with AI integration enabled. For local work, Docker is fastest.

requirements.txt:

conductor-python==3.22.0
pydantic==2.8.0
structlog==24.4.0
pytest==8.3.4
httpx==0.27.2
docker run -p 5000:5000 -p 8080:8080 conductoross/conductor:next
pip install -r requirements.txt
export CONDUCTOR_SERVER_URL=http://localhost:8080/api

config.py:

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    conductor_url: str = "http://localhost:8080/api"
    github_token_env: str = "CONDUCTOR_ENV_GH_TOKEN"
    llm_provider: str = "openai"
    model: str = "gpt-4o-mini"
    max_fanout: int = 2
    approval_timeout_h: int = 72

    class Config:
        env_prefix = "REVIEW_GRAPH_"

settings = Settings()

Never put the GitHub token in workflow input. Inputs are recorded with the execution. I made this mistake on day one and the token sat in execution history in plain text. Use the server-side environment provider. Set CONDUCTOR_ENV_GH_TOKEN in the server process before it starts.

Register the graph:

conductor workflow create ai/examples/35-governed-adaptive-agent.json
conductor workflow start --name governed_adaptive_pr_review \
  --input '{"repo":"saasnext/api","pr":482,"llmProvider":"openai"}'

Step 2: The four evidence passes in code

If you prefer Python SDK over raw JSON, here is the equivalent authoring path. Conductor compiles it into the same inspectable graph.

review_graph.py:

from conductor.client.workflow.conductor_workflow import ConductorWorkflow
from conductor.client.workflow.executor import WorkflowExecutor
from conductor.client.http.models import Task, TaskType
from config import settings

def build_review_graph(executor: WorkflowExecutor) -> ConductorWorkflow:
    wf = ConductorWorkflow(
        executor=executor,
        name="governed_adaptive_pr_review",
        version=1,
    )
    ctx = wf.add_task("read_pr_context", TaskType.LLM_CHAT_COMPLETE, {
        "model": settings.model,
        "messages": [{"role": "user", "content": "${workflow.input.pr_url}"}],
    })
    files = wf.add_task("inspect_files", TaskType.CALL_MCP_TOOL, {
        "tool": "github_list_changed_files",
        "args": {"pr": "${workflow.input.pr}"},
    })
    checks = wf.add_task("inspect_ci", TaskType.CALL_MCP_TOOL, {
        "tool": "github_list_check_runs",
        "args": {"pr": "${workflow.input.pr}"},
    })
    plan = wf.add_task("choose_deepdives", TaskType.LLM_CHAT_COMPLETE, {
        "model": settings.model,
        "allowed_paths": ["diff", "reviews", "comments"],
        "max_selected": settings.max_fanout,
    })
    fork = wf.add_task("bounded_fanout", TaskType.FORK_JOIN_DYNAMIC, {
        "paths": "${choose_deepdives.output.selected}",
    })
    synth = wf.add_task("synthesize", TaskType.LLM_CHAT_COMPLETE, {
        "model": settings.model,
        "ledger": ["${read_pr_context.output}", "${inspect_files.output}", "${inspect_ci.output}"],
    })
    approval = wf.add_task("human_gate", TaskType.HUMAN, {
        "assignment": "repo-owners",
        "timeoutHours": settings.approval_timeout_h,
    })
    ctx >> files >> checks >> plan >> fork >> synth >> approval
    wf.register()
    return wf

The run pauses after the fourth pass at the HUMAN task. Open http://localhost:5000, inspect each persisted assessment, then approve or reject. Approval payload becomes durable task output. Rejection ends the run with zero side effects.

This approval-as-task shape matches managed multi-agent runs: the human is an async boundary, not an exception.

Benchmarks from 140 real pull requests

Test setup at SaaSNext: Conductor OSS on a 4-vCPU VM, Postgres persistence, gpt-4o-mini, private monorepo, PRs ranging 3 to 400 files.

Metric Free-running agent Adaptive graph Delta
Unapproved posts 3 in 140 reviews 0 in 140 reviews Zero leaks
Median evidence latency 41s 2.1s per pass, 18s total Faster via bounded reads
Token cost per review $0.42 full-history replay $0.11 ledger synthesis -74% cost
Crash recovery (worker kill pass 3) Restart from zero Resume at pass 3 Zero rework
Approval wait (max observed) Process must stay alive 52 hrs parked, zero CPU $0 idle

Cost drop comes from ledger synthesis. The final LLM call reads four compact assessments, not 400 file diffs. Our largest PR previously blew a 128k window. The graph version summarized it in 6k tokens.

Crash test was deliberate. I killed the worker during pass 3 on a 200-file PR. Restart resumed at pass 3 with passes 1 and 2 intact. Total rework: none. That is the durability guarantee paying rent.

The reliability framing lines up with per-step reliability analysis: bounding fan-out and persisting each step dominates success rate more than any model upgrade.

Production war story: the unbounded fork incident

Second scar, and it was ours. We raised max_fanout to 8 for a monorepo PR touching 12 services. The model selected 8 deep-dives. Each pulled full diffs. One execution consumed 900k tokens and $14. The review was good. The bill was not.

Fix: hard cap at 2, plus a token budget guard. The SWITCH task now checks estimated diff size before forking. Diffs over 50k tokens get summarized first through a dedicated LLM pass. Added 30 lines of JSON. Per-review p99 cost fell from $14 to $0.31.

Also enforce output caps. Early runs stored full diffs in workflow variables. History replay slowed from 2s to 19s by turn 40. Now we store diff hashes plus 2k-token summaries, with full blobs in S3 referenced by URL. Small durable artifacts, not raw histories.

When NOT to use this pattern

Be direct about limits. Skip adaptive graphs when the task is a fixed pipeline with no runtime choices. A nightly ETL with three SQL steps does not need an agent choosing paths. A static workflow is cheaper and clearer.

Skip it for sub-second latency loops. Workflow task scheduling adds 20-50ms per step. Real-time autocomplete and game loops will feel it. Use in-process orchestration there.

Skip it if your team cannot run Conductor. It needs Java 21, Postgres, Elasticsearch for visibility, and worker versioning. Two engineers with no platform time should start with a single-tenant review script and migrate past 50 PRs per week.

Use it when side effects are consequential, approvals take hours, runs must survive deploys, or auditors ask why a comment posted. That is exactly the PR review case.

Ship checklist

  1. Enable conductor.integrations.ai.enabled. The AGENT task type silently no-ops without it.
  2. Keep tokens server-side. Never in workflow input or prompts.
  3. Cap fan-out at 2 and diff size at 50k tokens per branch.
  4. Set HUMAN timeout explicitly. Ours is 72 hours, then auto-reject.
  5. Version the graph. We keep the last known-good definition for one-click rollback.

Bottom line: ship the governed graph, not framework code. The agent adapts. The graph endures. Auditors can replay every decision.

By , Founder & Editor-in-Chief at Daily AI World.

Executive Briefing

Enjoyed this breakdown? Get our morning dispatch in your inbox.

Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.

🎉 Thank You for Subscribing!

Frequently Asked Questions
An adaptive graph lets the agent select next steps at runtime from an approved allowlist, while Conductor validates each choice, persists it as workflow state, and gates side effects with HUMAN approval. Free-running agents execute model output directly with no boundary.
Four passes: PR context, changed-file surface, CI check runs, then one or two approved deep-dives in bounded parallel. Each writes a compact assessment to a workflow variable. The final comment synthesizes from that ledger.
Zero custom workers for the reference graph. It uses only built-in tasks: LLM_CHAT_COMPLETE, CALL_MCP_TOOL, FORK_JOIN_DYNAMIC, HUMAN, SWITCH, and transforms. Set the GitHub token server-side and register the JSON.
$0.11 versus $0.42 in our tests, a 74% drop. Ledger synthesis reads four compact assessments instead of full diffs, and bounded fan-out caps token-hungry branches.
Deepak Bagada
Author Profile

Deepak Bagada

Founder & Editor-in-Chief

Deepak Bagada is the founder and Editor-in-Chief of Daily AI World and CEO of SaaSNext. He covers enterprise AI architecture, high-concurrency agent workflows, Model Context Protocol tooling, and frontier AI systems engineering.

Related Intelligence Analysis

Research Breakdown AI Workflows

The Step-by-Step Guide to Automating Meeting Tasks with Whisper

You're spending 45 minutes after every client meeting typing up notes and manually assigning tasks in Jira. This guide shows you how to wire OpenAI Whisper and Claude to automatically convert meeting recordings into assi...

Deepak Bagada Deepak Bagada
9m read
Research Breakdown AI Workflows

Lovable AI UI-to-Code Pipeline: 2026 Tutorial

Lovable AI UI-to-code automation pipeline uses Lovable AI on Lovable Cloud to convert visual UI designs and natural language specs into production-grade web applications. UI/UX designers and frontend developers bridging...

Deepak Bagada Deepak Bagada
8m read
Breaking AI Workflows

Claude Code's New Browser: 5 Workflows That Save Hours Daily

Claude Code's built-in browser is a sandboxed tabbed browser inside the Claude Code desktop app (Week 28, July 2026) accessible via Cmd+Shift+B (macOS) or Ctrl+Shift+B (Windows). It lets Claude open websites, read docume...

Deepak Bagada Deepak Bagada
12m read
Audio Briefing
Accessibility Preferences
High Contrast Mode
Accessible Reading Font

Keyboard Shortcuts

Open Search Dialog ⌘K or /
Toggle Theme (Dark/Light) t
Toggle Audio Player a
Open Shortcuts Menu ?
Close Active Dialog Esc

Cookie & Privacy Preferences

We use cookies and telemetry tools to deliver technical dispatches, benchmark analytics, and advertising via Google AdSense. Review our Privacy Policy.