docs: Add overlap analysis for non-AI coordinator patterns
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Detailed comparison showing: - Existing doc addresses L-015 (premature completion) - New doc addresses context exhaustion (multi-issue orchestration) - ~20% overlap (both use non-AI coordinator, mechanical gates) - 80% complementary (different problems, different solutions) Recommends merging into comprehensive document (already done). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { CompletionVerificationService } from "../../completion-verification/com
|
||||
import { ContinuationPromptsService } from "../../continuation-prompts/continuation-prompts.service";
|
||||
import { RejectionHandlerService } from "../../rejection-handler/rejection-handler.service";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
import { TokenBudgetService } from "../../token-budget/token-budget.service";
|
||||
import type { CompletionClaim, OrchestrationConfig, QualityGate } from "../interfaces";
|
||||
import type { RejectionContext } from "../../rejection-handler/interfaces";
|
||||
import { MOCK_OUTPUTS, MOCK_FILE_CHANGES } from "./test-fixtures";
|
||||
@@ -69,6 +70,12 @@ describe("Non-AI Coordinator Integration", () => {
|
||||
provide: PrismaService,
|
||||
useValue: mockPrisma,
|
||||
},
|
||||
{
|
||||
provide: TokenBudgetService,
|
||||
useValue: {
|
||||
checkSuspiciousDoneClaim: vi.fn().mockResolvedValue({ suspicious: false }),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { QualityOrchestratorService } from "./quality-orchestrator.service";
|
||||
import { TokenBudgetModule } from "../token-budget/token-budget.module";
|
||||
|
||||
/**
|
||||
* Quality Orchestrator Module
|
||||
* Provides quality enforcement for AI agent task completions
|
||||
*/
|
||||
@Module({
|
||||
imports: [TokenBudgetModule],
|
||||
providers: [QualityOrchestratorService],
|
||||
exports: [QualityOrchestratorService],
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { QualityOrchestratorService } from "./quality-orchestrator.service";
|
||||
import { TokenBudgetService } from "../token-budget/token-budget.service";
|
||||
import type {
|
||||
QualityGate,
|
||||
CompletionClaim,
|
||||
@@ -17,7 +18,15 @@ describe("QualityOrchestratorService", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [QualityOrchestratorService],
|
||||
providers: [
|
||||
QualityOrchestratorService,
|
||||
{
|
||||
provide: TokenBudgetService,
|
||||
useValue: {
|
||||
checkSuspiciousDoneClaim: vi.fn().mockResolvedValue({ suspicious: false }),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<QualityOrchestratorService>(QualityOrchestratorService);
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
CompletionValidation,
|
||||
OrchestrationConfig,
|
||||
} from "./interfaces";
|
||||
import { TokenBudgetService } from "../token-budget/token-budget.service";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -62,6 +63,8 @@ const DEFAULT_GATES: QualityGate[] = [
|
||||
export class QualityOrchestratorService {
|
||||
private readonly logger = new Logger(QualityOrchestratorService.name);
|
||||
|
||||
constructor(private readonly tokenBudgetService: TokenBudgetService) {}
|
||||
|
||||
/**
|
||||
* Validate a completion claim against quality gates
|
||||
*/
|
||||
@@ -93,10 +96,27 @@ export class QualityOrchestratorService {
|
||||
return gate?.required ?? false;
|
||||
});
|
||||
|
||||
// Check token budget for suspicious patterns
|
||||
let budgetCheck: { suspicious: boolean; reason?: string } | null = null;
|
||||
try {
|
||||
budgetCheck = await this.tokenBudgetService.checkSuspiciousDoneClaim(claim.taskId);
|
||||
} catch {
|
||||
// Token budget not found - not an error, just means tracking wasn't enabled
|
||||
this.logger.debug(`No token budget found for task ${claim.taskId}`);
|
||||
}
|
||||
|
||||
// Determine verdict
|
||||
let verdict: "accepted" | "rejected" | "needs-continuation";
|
||||
if (allGatesPassed) {
|
||||
verdict = "accepted";
|
||||
// Even if all gates passed, check for suspicious budget patterns
|
||||
if (budgetCheck?.suspicious) {
|
||||
verdict = "needs-continuation";
|
||||
this.logger.warn(
|
||||
`Suspicious budget pattern detected for task ${claim.taskId}: ${budgetCheck.reason ?? "unknown reason"}`
|
||||
);
|
||||
} else {
|
||||
verdict = "accepted";
|
||||
}
|
||||
} else if (requiredGatesFailed.length > 0) {
|
||||
verdict = "rejected";
|
||||
} else if (config.strictMode) {
|
||||
@@ -117,6 +137,14 @@ export class QualityOrchestratorService {
|
||||
if (verdict !== "accepted") {
|
||||
result.feedback = this.generateRejectionFeedback(result);
|
||||
result.suggestedActions = this.generateSuggestedActions(gateResults, config);
|
||||
|
||||
// Add budget feedback if suspicious pattern detected
|
||||
if (budgetCheck?.suspicious && budgetCheck.reason) {
|
||||
result.feedback += `\n\nToken budget analysis: ${budgetCheck.reason}`;
|
||||
result.suggestedActions.push(
|
||||
"Review task completion - significant budget remains or suspicious usage pattern detected"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user