feat(#139): build Gate Rejection Response Handler
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Implement rejection handling for tasks that fail quality gates after
all continuation attempts are exhausted.

Schema:
- Add TaskRejection model for tracking rejections
- Store failures, attempts, escalation state

Service:
- handleRejection: Main entry point for rejection handling
- logRejection: Database logging
- determineEscalation: Rule-based escalation determination
- executeEscalation: Execute escalation actions
- sendNotification: Notification dispatch
- markForManualReview: Flag tasks for human review
- getRejectionHistory: Query rejection history
- generateRejectionReport: Markdown report generation

Escalation rules:
- max-attempts: Trigger after 3+ attempts
- time-exceeded: Trigger after 2+ hours
- critical-failure: Trigger on security/critical issues

Actions: notify, block, reassign, cancel

Tests: 16 passing with 80% statement coverage

Fixes #139

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 14:01:42 -06:00
parent 0387cce116
commit a86d304f07
8 changed files with 926 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
export interface EscalationRule {
condition: "max-attempts" | "critical-failure" | "time-exceeded";
action: "notify" | "reassign" | "block" | "cancel";
target?: string; // notification target
priority: "low" | "medium" | "high" | "critical";
}
export interface EscalationConfig {
rules: EscalationRule[];
notifyOnRejection: boolean;
autoReassign: boolean;
maxWaitTime: number; // minutes before auto-escalation
}

View File

@@ -0,0 +1,2 @@
export * from "./rejection.interface";
export * from "./escalation.interface";

View File

@@ -0,0 +1,25 @@
export interface RejectionContext {
taskId: string;
workspaceId: string;
agentId: string;
attemptCount: number;
failures: FailureSummary[];
originalTask: string;
startedAt: Date;
rejectedAt: Date;
}
export interface FailureSummary {
gateName: string;
failureType: string;
message: string;
attempts: number;
}
export interface RejectionResult {
handled: boolean;
escalated: boolean;
notificationsSent: string[];
taskState: "blocked" | "reassigned" | "cancelled";
manualReviewRequired: boolean;
}