What to build
Replace the monolithic switch (command.type) in decideOrchestrationCommand (apps/server/src/orchestration/decider.ts, 976 lines) with a CommandHandlerRegistry that dispatches by command type.
Registry design:
type CommandHandler = (command: OrchestrationCommand, readModel: OrchestrationReadModel) =>
Effect<DecideOrchestrationCommandResult, OrchestrationCommandInvariantError | PlatformError>;
registry.register("thread.archive-and-new", handleArchiveAndNew)
registry.register("thread.context.trim", handleContextTrim)
registry.register("thread.context.compact", handleContextCompact)
registry.register("thread.context.summarize", handleContextSummarize)
registry.register("project.create", handleProjectCreate)
// ... etc
The decider becomes:
const handler = registry.get(command.type);
if (!handler) throw new Error(`No handler for command type: ${command.type}`);
return yield* handler(command, readModel);
Migrate these commands to individual handler files:
- All 4 h-code commands:
archive-and-new, context.trim, context.compact, context.summarize
- At least 3 upstream commands (to prove the pattern works for both): e.g.
project.create, thread.create, thread.delete
Each handler moves to its own file with its invariants co-located.
Acceptance criteria
Blocked by
What to build
Replace the monolithic
switch (command.type)indecideOrchestrationCommand(apps/server/src/orchestration/decider.ts, 976 lines) with aCommandHandlerRegistrythat dispatches by command type.Registry design:
The decider becomes:
Migrate these commands to individual handler files:
archive-and-new,context.trim,context.compact,context.summarizeproject.create,thread.create,thread.deleteEach handler moves to its own file with its invariants co-located.
Acceptance criteria
CommandHandlerRegistrybuilt (reusingMethodRegistrypattern from Pre-factor: MethodRegistry generic utility #132)decideOrchestrationCommandreplaced with registry dispatchhandlers/archiveAndNew.ts)decideCommandSequencewhich delegates to registered handlers)decider.contextTrim.test.tsanddecider.archiveAndNew.test.tsstill passvp checkandvp run typecheckpassBlocked by