Remove task-level approval system

Task-level approval (requiresApproval, mergeRequiresApproval,
pending_approval status) was redundant with executionMode
(yolo vs review_per_phase) and blocked the orchestrator's
phase completion flow. Tasks now complete directly;
phase-level review via executionMode is the right granularity.

Removed: schema columns (left in DB, removed from Drizzle),
TaskPendingApprovalEvent, approveTask/listPendingApprovals
procedures, findPendingApproval repository method, and all
frontend approval UI.
This commit is contained in:
Lukas May
2026-03-05 17:09:48 +01:00
parent 209629241d
commit 8804455c77
27 changed files with 48 additions and 237 deletions

View File

@@ -204,7 +204,6 @@ export function initiativeProcedures(publicProcedure: ProcedureBuilder) {
updateInitiativeConfig: publicProcedure
.input(z.object({
initiativeId: z.string().min(1),
mergeRequiresApproval: z.boolean().optional(),
executionMode: z.enum(['yolo', 'review_per_phase']).optional(),
branch: z.string().nullable().optional(),
}))

View File

@@ -38,7 +38,7 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
updateTaskStatus: publicProcedure
.input(z.object({
id: z.string().min(1),
status: z.enum(['pending_approval', 'pending', 'in_progress', 'completed', 'blocked']),
status: z.enum(['pending', 'in_progress', 'completed', 'blocked']),
}))
.mutation(async ({ ctx, input }) => {
const taskRepository = requireTaskRepository(ctx);
@@ -59,7 +59,6 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
description: z.string().optional(),
category: z.enum(['execute', 'research', 'discuss', 'plan', 'detail', 'refine', 'verify', 'merge', 'review']).optional(),
type: z.enum(['auto', 'checkpoint:human-verify', 'checkpoint:decision', 'checkpoint:human-action']).optional(),
requiresApproval: z.boolean().nullable().optional(),
}))
.mutation(async ({ ctx, input }) => {
const taskRepository = requireTaskRepository(ctx);
@@ -79,7 +78,6 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
description: input.description ?? null,
category: input.category ?? 'execute',
type: input.type ?? 'auto',
requiresApproval: input.requiresApproval ?? null,
status: 'pending',
});
}),
@@ -91,7 +89,6 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
description: z.string().optional(),
category: z.enum(['execute', 'research', 'discuss', 'plan', 'detail', 'refine', 'verify', 'merge', 'review']).optional(),
type: z.enum(['auto', 'checkpoint:human-verify', 'checkpoint:decision', 'checkpoint:human-action']).optional(),
requiresApproval: z.boolean().nullable().optional(),
}))
.mutation(async ({ ctx, input }) => {
const taskRepository = requireTaskRepository(ctx);
@@ -111,22 +108,10 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
description: input.description ?? null,
category: input.category ?? 'execute',
type: input.type ?? 'auto',
requiresApproval: input.requiresApproval ?? null,
status: 'pending',
});
}),
listPendingApprovals: publicProcedure
.input(z.object({
initiativeId: z.string().optional(),
phaseId: z.string().optional(),
category: z.enum(['execute', 'research', 'discuss', 'plan', 'detail', 'refine', 'verify', 'merge', 'review']).optional(),
}).optional())
.query(async ({ ctx, input }) => {
const taskRepository = requireTaskRepository(ctx);
return taskRepository.findPendingApproval(input);
}),
listInitiativeTasks: publicProcedure
.input(z.object({ initiativeId: z.string().min(1) }))
.query(async ({ ctx, input }) => {
@@ -196,12 +181,5 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) {
return edges;
}),
approveTask: publicProcedure
.input(z.object({ taskId: z.string().min(1) }))
.mutation(async ({ ctx, input }) => {
const dispatchManager = requireDispatchManager(ctx);
await dispatchManager.approveTask(input.taskId);
return { success: true };
}),
};
}