feat: implement CI (Continuous Intelligence) autonomous engineering harness
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/)
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
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())
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user