9cf5c000d9
Implements the full PRD for CI - a fully autonomous AI-driven software engineering harness derived from Learnship's architecture. Core components: - CI Orchestrator agent with autonomous pipeline (SPECIFY → CLARIFY → RESEARCH → PLAN → EXECUTE → VERIFY → COMPLETE) - Decision Engine with confidence thresholds (high/medium/low) - Clarify Phase with question budget and default acceptance - Escalation Protocol with timeout auto-proceed - Audit Trail system (.ci/audit/) for post-hoc review - Error Recovery with retry, plan revision, and rollback 18 agents (all Learnship agents + Orchestrator): - Autonomous behavioral modifications per PRD §7.1 - Agent registry with factory pattern 11 CLI commands: - ci init, ci run, ci quick, ci debug, ci verify - ci review, ci status, ci audit, ci clarify - ci rollback, ci ship 4-layer verification system: - Structural, Behavioral, Security, Code Quality 3 autonomy levels: full, supervised, guided Compatible with Learnship artifact schemas (.planning/)
116 lines
3.0 KiB
TypeScript
116 lines
3.0 KiB
TypeScript
import * as crypto from "node:crypto";
|
|
import { Decision, DecisionCategory, Alternative, confidenceToLevel } from "../types/decisions.js";
|
|
import { CIConfig } from "../types/config.js";
|
|
import { logDecision } from "./audit.js";
|
|
|
|
export interface DecisionInput {
|
|
decision: string;
|
|
rationale: string;
|
|
confidence: number;
|
|
category: DecisionCategory;
|
|
alternatives_considered: Alternative[];
|
|
learnship_equivalent: string;
|
|
phase?: string;
|
|
task?: string;
|
|
}
|
|
|
|
export interface DecisionResult {
|
|
decision: Decision;
|
|
escalated: boolean;
|
|
reason?: string;
|
|
}
|
|
|
|
export class DecisionEngine {
|
|
private config: CIConfig;
|
|
private projectPath: string;
|
|
private currentPhase: number;
|
|
private decisionCounter: number;
|
|
|
|
constructor(config: CIConfig, projectPath: string) {
|
|
this.config = config;
|
|
this.projectPath = projectPath;
|
|
this.currentPhase = 0;
|
|
this.decisionCounter = 0;
|
|
}
|
|
|
|
setPhase(phase: number): void {
|
|
this.currentPhase = phase;
|
|
}
|
|
|
|
makeDecision(input: DecisionInput): DecisionResult {
|
|
const id = `D-${String(++this.decisionCounter).padStart(3, "0")}`;
|
|
const threshold = this.config.autonomy.decision_confidence_threshold;
|
|
|
|
const decision: Decision = {
|
|
id,
|
|
timestamp: new Date().toISOString(),
|
|
decision: input.decision,
|
|
rationale: input.rationale,
|
|
confidence: input.confidence,
|
|
category: input.category,
|
|
alternatives_considered: input.alternatives_considered,
|
|
learnship_equivalent: input.learnship_equivalent,
|
|
human_override: null,
|
|
phase: input.phase,
|
|
task: input.task,
|
|
};
|
|
|
|
logDecision(this.projectPath, this.currentPhase, decision);
|
|
|
|
const confidenceLevel = confidenceToLevel(input.confidence);
|
|
|
|
if (input.confidence < threshold) {
|
|
return {
|
|
decision,
|
|
escalated: true,
|
|
reason: `Confidence ${input.confidence.toFixed(2)} below threshold ${threshold} (${confidenceLevel})`,
|
|
};
|
|
}
|
|
|
|
return { decision, escalated: false };
|
|
}
|
|
|
|
makeHighConfidenceDecision(
|
|
decision: string,
|
|
rationale: string,
|
|
category: DecisionCategory,
|
|
alternatives: Alternative[] = [],
|
|
learnship_equivalent: string = ""
|
|
): DecisionResult {
|
|
return this.makeDecision({
|
|
decision,
|
|
rationale,
|
|
confidence: 0.95,
|
|
category,
|
|
alternatives_considered: alternatives,
|
|
learnship_equivalent,
|
|
});
|
|
}
|
|
|
|
makeMediumConfidenceDecision(
|
|
decision: string,
|
|
rationale: string,
|
|
category: DecisionCategory,
|
|
alternatives: Alternative[] = [],
|
|
learnship_equivalent: string = ""
|
|
): DecisionResult {
|
|
return this.makeDecision({
|
|
decision,
|
|
rationale,
|
|
confidence: 0.7,
|
|
category,
|
|
alternatives_considered: alternatives,
|
|
learnship_equivalent,
|
|
});
|
|
}
|
|
|
|
shouldAutoDecide(confidence: number): boolean {
|
|
return confidence >= this.config.autonomy.decision_confidence_threshold;
|
|
}
|
|
|
|
isIrreversibleAction(action: string): boolean {
|
|
return this.config.autonomy.escalation_hooks.some((hook) =>
|
|
action.toLowerCase().includes(hook.toLowerCase())
|
|
);
|
|
}
|
|
} |