Overview
Version: v10.5.0 Scale & Reliability
Effort: L · 7–10 days
Branch: feature/s01-distributed-debates
Enable Delibera to distribute debate round execution across multiple workers using Redis as the coordination backbone. Each council member turn becomes an independent work item that any available worker can pick up and execute, enabling true horizontal scaling for large councils and high-throughput deployments.
Architecture
┌───────────────────────────────┐
│ Delibera.Server (coordinator) │
│ POST /api/v1/debates │
└───────────────────────────────┘
│ RedisDebateOrchestrator
│ publishes MemberTurnJob
┌───┴───┐ ┌───────┐ ┌───────┐
│Worker A│ │Worker B│ │Worker C│
│Architect│ │TechLead│ │ DevOps │
└────────┘ └───────┘ └───────┘
│ │ │
└───────┬───────┘
│ Redis Streams
┌─────┴─────┐
│ Aggregator │
│ (Chairman) │
└─────────────┘
Core Interfaces
// New interface — replaces direct CouncilExecutor call for distributed mode
public interface IDebateOrchestrator
{
Task<DebateRecord> StartAsync(ScenarioRequest request, CancellationToken ct = default);
Task<DebateRecord> GetStatusAsync(string debateId, CancellationToken ct = default);
Task CancelAsync(string debateId, CancellationToken ct = default);
IAsyncEnumerable<DebateRoundEvent> StreamAsync(string debateId, CancellationToken ct = default);
}
// Local (current) implementation — no change in behavior
public class LocalDebateOrchestrator : IDebateOrchestrator { ... }
// New distributed implementation
public class RedisDebateOrchestrator : IDebateOrchestrator
{
// Uses Redis Streams for job queue + pub/sub for round events
// Uses Redis Hash for debate state
// Uses Redis sorted set for round ordering
}
Redis Data Model
| Key Pattern |
Type |
Content |
delibera:debate:{id}:state |
Hash |
DebateRecord fields |
delibera:debate:{id}:rounds |
Sorted Set |
Round results, score = round index |
delibera:debate:{id}:events |
Stream |
DebateRoundEvent, DebateCompletedEvent |
delibera:jobs:{id} |
Stream |
MemberTurnJob items (consumer group per worker) |
delibera:debates:active |
Set |
IDs of running debates |
Worker Service
// New hosted service — runs in every Delibera.Server instance or standalone worker
public class DebateWorkerService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await foreach (var job in _jobQueue.DequeueAsync(stoppingToken))
{
var result = await _memberExecutor.ExecuteTurnAsync(job, stoppingToken);
await _resultPublisher.PublishAsync(job.DebateId, result, stoppingToken);
}
}
}
CouncilBuilder Integration
// Opt-in to distributed mode via builder
services.AddDelibera()
.UseRedisOrchestrator(connectionString: "localhost:6379",
workerCount: 4,
consumerGroup: "delibera-workers");
// OR per-debate via options
councilBuilder.WithDistributedExecution(orchestrator);
Tasks
Acceptance Criteria
Labels
enhancement, v10.5.0, distributed, redis
Overview
Version: v10.5.0 Scale & Reliability
Effort: L · 7–10 days
Branch:
feature/s01-distributed-debatesEnable Delibera to distribute debate round execution across multiple workers using Redis as the coordination backbone. Each council member turn becomes an independent work item that any available worker can pick up and execute, enabling true horizontal scaling for large councils and high-throughput deployments.
Architecture
Core Interfaces
Redis Data Model
delibera:debate:{id}:statedelibera:debate:{id}:roundsdelibera:debate:{id}:eventsdelibera:jobs:{id}delibera:debates:activeWorker Service
CouncilBuilder Integration
Tasks
IDebateOrchestratorinDelibera.Core.InterfacesLocalDebateOrchestratorwrapping currentCouncilExecutor(no behavior change)RedisDebateOrchestratorusing StackExchange.RedisMemberTurnJobrecord (debateId, round, member, context snapshot)DebateWorkerService(BackgroundService) for consuming jobsUseRedisOrchestrator(...)DI extension inDelibera.ServerDebateEndpointsto useIDebateOrchestratorinstead of direct executorMemberTurnExecutespan withworker.idattributeDelibera.Workerstandalone worker project (optional sidecar)docs/distributed.mdwith architecture diagram and deployment guideAcceptance Criteria
LocalDebateOrchestratoris the default — no behavior change without Redis configRedisDebateOrchestratorcorrectly distributes member turns across workers/streamendpoint works with Redis-backed eventsCancelAsynccorrectly stops all workers processing that debateLabels
enhancement,v10.5.0,distributed,redis