Implementation Plan: Core Abstractions
Implementation Plan: Core Abstractions
Plan: 03-core-abstractions.md Date: 2026-02-07 Status: Ready for Implementation Section: SYSTEM-DESIGN.md Section 3 - Core Abstractions
Executive Summary
This plan details the complete implementation of Forge's six core types: Agent, ForgeEvent, Tool, Phase, Memory, and Checkpoint. These abstractions are the foundation upon which the entire system is built. Every other module will compose these types. This implementation must be comprehensive, type-safe, and production-ready.
Key Deliverable: /home/clawdbot/projects/agentic-dev-research/src/core/types.ts containing all core type definitions, enums, discriminated unions, and supporting types with complete TypeScript type safety.
1. Agent Interface
1.1 Core Agent Interface
typescript// ─── Agent Type Enum ─────────────────────────────────────── export enum AgentType { PLANNER = 'planner', IMPLEMENTER = 'implementer', REVIEWER = 'reviewer', TESTER = 'tester', DEPLOYER = 'deployer', MONITOR = 'monitor', LEARNER = 'learner', META = 'meta' } // ─── Agent Interface ─────────────────────────────────────── export interface Agent<TInput = PhaseInput, TOutput = PhaseOutput> { /** Unique agent identifier */ id: AgentId; /** Agent type from enum */ type: AgentType; /** Human-readable name */ name: string; /** Agent version for tracking changes */ version: string; /** Available tools for this agent */ tools: Tool[]; /** System prompt template */ systemPrompt: string; /** Execute one cycle of the agent loop */ execute(input: TInput, ctx: AgentContext): Promise<TOutput>; /** Optional: Validate input before execution */ validateInput?(input: TInput): Promise<ValidationResult>; /** Optional: Validate output after execution */ validateOutput?(output: TOutput): Promise<ValidationResult>; } // ─── Agent Context (what every agent receives) ───────────── export interface AgentContext { /** Unique trace ID for this pipeline run */ traceId: TraceId; /** Current session ID */ sessionId: string; /** Event bus for emitting events */ bus: EventBus; /** Memory system for recall and storage */ memory: MemorySystem; /** LLM provider for reasoning */ llm: LLMProvider; /** Safety controls */ safety: SafetyControls; /** Current cost accumulation (USD) */ cost: CostTracker; /** Elapsed time in current phase (ms) */ elapsed: number; /** Checkpoint system for state persistence */ checkpoint: CheckpointSystem; /** Tool registry for discovering and executing tools */ tools: ToolRegistry; /** Configuration for this run */ config: RuntimeConfig; /** Logger scoped to this agent */ logger: Logger; } // ─── Agent Identifiers ───────────────────────────────────── export type AgentId = string; // Format: "agent:<type>:<ulid>" export type TraceId = string; // Format: "trace:<ulid>"
1.2 Phase Input/Output Types
typescript// ─── Phase Name Enum ─────────────────────────────────────── export enum PhaseName { PLANNING = 'planning', IMPLEMENTATION = 'implementation', REVIEW = 'review', TESTING = 'testing', DEPLOYMENT = 'deployment', MONITORING = 'monitoring' } // ─── Phase Input (discriminated union by phase) ──────────── export type PhaseInput = | PlanningInput | ImplementationInput | ReviewInput | TestingInput | DeploymentInput | MonitoringInput; export interface PlanningInput { phase: PhaseName.PLANNING; task: string; // Natural language task description requirements?: Requirements; constraints?: Constraint[]; context?: string; // Additional context } export interface ImplementationInput { phase: PhaseName.IMPLEMENTATION; plan: ImplementationPlan; existingCode?: Codebase; fixFindings?: Finding[]; // From review phase bounce-back fixFailures?: FailureAnalysis[]; // From test phase bounce-back } export interface ReviewInput { phase: PhaseName.REVIEW; code: Codebase; plan: ImplementationPlan; riskScore?: RiskScore; // From planning } export interface TestingInput { phase: PhaseName.TESTING; code: Codebase; plan: ImplementationPlan; existingTests?: TestSuite; } export interface DeploymentInput { phase: PhaseName.DEPLOYMENT; code: Codebase; tests: TestResults; review: ReviewResult; environment: 'staging' | 'production'; } export interface MonitoringInput { phase: PhaseName.MONITORING; deployment: Deployment; duration: number; // How long to monitor (ms) } // ─── Phase Output (discriminated union by phase) ─────────── export type PhaseOutput = | PlanningOutput | ImplementationOutput | ReviewOutput | TestingOutput | DeploymentOutput | MonitoringOutput; export interface PlanningOutput { phase: PhaseName.PLANNING; plan: ImplementationPlan; analysis: RequirementsAnalysis; architecture: Architecture; riskScore: RiskScore; estimates: Estimates; } export interface ImplementationOutput { phase: PhaseName.IMPLEMENTATION; code: Codebase; changes: FileChange[]; validated: boolean; // Typecheck + basic validation passed metrics: ImplementationMetrics; } export interface ReviewOutput { phase: PhaseName.REVIEW; findings: Finding[]; riskScore: RiskScore; decision: ReviewDecision; analysis: ReviewAnalysis; } export interface TestingOutput { phase: PhaseName.TESTING; results: TestResults; coverage: CoverageReport; failures: FailureAnalysis[]; generatedTests?: TestCase[]; } export interface DeploymentOutput { phase: PhaseName.DEPLOYMENT; deployment: Deployment; status: DeploymentStatus; metrics: DeploymentMetrics; healthChecks: HealthCheckResult[]; } export interface MonitoringOutput { phase: PhaseName.MONITORING; metrics: RuntimeMetrics; anomalies: Anomaly[]; feedback: RuntimeFeedback; recommendations: Recommendation[]; }
1.3 Supporting Types for Agent
typescript// ─── Validation ──────────────────────────────────────────── export interface ValidationResult { valid: boolean; errors: ValidationError[]; warnings: ValidationWarning[]; } export interface ValidationError { field: string; message: string; code: string; } export interface ValidationWarning { field: string; message: string; code: string; } // ─── Cost Tracking ───────────────────────────────────────── export interface CostTracker { current: number; // USD budget: number; // USD byPhase: Record<PhaseName, number>; tokens: { prompt: number; completion: number; total: number; }; add(cost: number, phase: PhaseName, tokens?: TokenUsage): void; remaining(): number; percentUsed(): number; } export interface TokenUsage { prompt: number; completion: number; } // ─── Safety Controls ─────────────────────────────────────── export interface SafetyControls { breakers: CircuitBreakerManager; gates: HumanGateManager; budget: BudgetManager; check(context: SafetyCheckContext): BreakerResult; } export interface SafetyCheckContext { iteration: number; cost: CostTracker; elapsed: number; phase: PhaseName; } export interface BreakerResult { shouldBreak: boolean; reason?: string; breaker?: string; limit?: number; current?: number; }
2. ForgeEvent Type
2.1 Core Event Interface
typescript// ─── Base Event Interface ────────────────────────────────── export interface ForgeEvent<TPayload = unknown> { /** Event ID (ULID) */ id: string; /** Trace ID - groups events in one pipeline run */ traceId: TraceId; /** Event timestamp */ timestamp: Date; /** Source agent/component that emitted this event */ source: string; /** Event type (dot-namespaced) */ type: EventType; /** Event-specific payload */ payload: TPayload; /** Current phase when event was emitted */ phase?: PhaseName; /** Optional cost information */ cost?: EventCost; /** Optional duration information (ms) */ duration?: number; /** Event metadata */ metadata?: EventMetadata; } export interface EventCost { tokens: number; usd: number; } export interface EventMetadata { userId?: string; sessionId?: string; environment?: string; version?: string; [key: string]: unknown; }
2.2 Event Type Enum (Complete List)
typescript// ─── Event Types ─────────────────────────────────────────── export enum EventType { // Run lifecycle RUN_STARTED = 'run.started', RUN_COMPLETED = 'run.completed', RUN_FAILED = 'run.failed', RUN_CANCELLED = 'run.cancelled', // Phase lifecycle PHASE_ENTERED = 'phase.entered', PHASE_COMPLETED = 'phase.completed', PHASE_FAILED = 'phase.failed', PHASE_BOUNCED = 'phase.bounced', // Agent lifecycle AGENT_STARTED = 'agent.started', AGENT_ITERATION = 'agent.iteration', AGENT_COMPLETED = 'agent.completed', AGENT_FAILED = 'agent.failed', AGENT_REFLECTED = 'agent.reflected', // Tool execution TOOL_CALLED = 'tool.called', TOOL_COMPLETED = 'tool.completed', TOOL_FAILED = 'tool.failed', // Review events FINDING_DETECTED = 'finding.detected', RISK_ASSESSED = 'risk.assessed', REVIEW_COMPLETED = 'review.completed', // Testing events TEST_STARTED = 'test.started', TEST_PASSED = 'test.passed', TEST_FAILED = 'test.failed', TEST_SKIPPED = 'test.skipped', TEST_FLAKY = 'test.flaky', // Deployment events DEPLOYMENT_STARTED = 'deployment.started', DEPLOYMENT_PROGRESSED = 'deployment.progressed', DEPLOYMENT_COMPLETED = 'deployment.completed', DEPLOYMENT_ROLLED_BACK = 'deployment.rolled_back', // Monitoring events METRIC_COLLECTED = 'metric.collected', ANOMALY_DETECTED = 'anomaly.detected', ALERT_TRIGGERED = 'alert.triggered', // Human interaction GATE_REQUESTED = 'gate.requested', GATE_APPROVED = 'gate.approved', GATE_REJECTED = 'gate.rejected', GATE_TIMEOUT = 'gate.timeout', // Safety events BREAKER_TRIPPED = 'breaker.tripped', BREAKER_RESET = 'breaker.reset', COST_THRESHOLD_REACHED = 'cost.threshold_reached', // Memory events MEMORY_STORED = 'memory.stored', MEMORY_RECALLED = 'memory.recalled', MEMORY_CONSOLIDATED = 'memory.consolidated', MEMORY_PRUNED = 'memory.pruned', // Checkpoint events CHECKPOINT_CREATED = 'checkpoint.created', CHECKPOINT_RESTORED = 'checkpoint.restored', // Error events ERROR_OCCURRED = 'error.occurred', ERROR_RECOVERED = 'error.recovered', ERROR_ESCALATED = 'error.escalated' }
2.3 Typed Event Payloads (Discriminated Union)
typescript// ─── Discriminated Union of All Event Payloads ───────────── export type TypedForgeEvent = | RunStartedEvent | RunCompletedEvent | PhaseEnteredEvent | PhaseCompletedEvent | AgentIterationEvent | ToolCalledEvent | FindingDetectedEvent | TestFailedEvent | GateRequestedEvent | BreakerTrippedEvent | MemoryStoredEvent | ErrorOccurredEvent; // ... (add all event types) // ─── Run Events ──────────────────────────────────────────── export interface RunStartedEvent extends ForgeEvent<RunStartedPayload> { type: EventType.RUN_STARTED; } export interface RunStartedPayload { task: string; config: RuntimeConfig; estimatedCost?: number; } export interface RunCompletedEvent extends ForgeEvent<RunCompletedPayload> { type: EventType.RUN_COMPLETED; } export interface RunCompletedPayload { outcome: 'success' | 'failure' | 'partial'; phases: PhaseName[]; totalCost: number; totalDuration: number; artifacts: string[]; } // ─── Phase Events ────────────────────────────────────────── export interface PhaseEnteredEvent extends ForgeEvent<PhaseEnteredPayload> { type: EventType.PHASE_ENTERED; } export interface PhaseEnteredPayload { phase: PhaseName; input: PhaseInput; checkpoint?: string; // Checkpoint ID } export interface PhaseCompletedEvent extends ForgeEvent<PhaseCompletedPayload> { type: EventType.PHASE_COMPLETED; } export interface PhaseCompletedPayload { phase: PhaseName; output: PhaseOutput; duration: number; cost: number; } // ─── Agent Events ────────────────────────────────────────── export interface AgentIterationEvent extends ForgeEvent<AgentIterationPayload> { type: EventType.AGENT_ITERATION; } export interface AgentIterationPayload { agent: AgentId; agentType: AgentType; iteration: number; decision: string; // LLM decision toolCalled?: string; reasoning?: string; } // ─── Tool Events ─────────────────────────────────────────── export interface ToolCalledEvent extends ForgeEvent<ToolCalledPayload> { type: EventType.TOOL_CALLED; } export interface ToolCalledPayload { tool: string; input: unknown; agent: AgentId; } // ─── Review Events ───────────────────────────────────────── export interface FindingDetectedEvent extends ForgeEvent<FindingDetectedPayload> { type: EventType.FINDING_DETECTED; } export interface FindingDetectedPayload { finding: Finding; source: 'static' | 'security' | 'ai'; } // ─── Test Events ─────────────────────────────────────────── export interface TestFailedEvent extends ForgeEvent<TestFailedPayload> { type: EventType.TEST_FAILED; } export interface TestFailedPayload { testId: string; testName: string; error: string; file?: string; line?: number; } // ─── Gate Events ─────────────────────────────────────────── export interface GateRequestedEvent extends ForgeEvent<GateRequestedPayload> { type: EventType.GATE_REQUESTED; } export interface GateRequestedPayload { gateId: string; gateType: HumanGateType; context: unknown; deadline: Date; } // ─── Breaker Events ──────────────────────────────────────── export interface BreakerTrippedEvent extends ForgeEvent<BreakerTrippedPayload> { type: EventType.BREAKER_TRIPPED; } export interface BreakerTrippedPayload { breaker: string; limit: number; current: number; phase: PhaseName; } // ─── Memory Events ───────────────────────────────────────── export interface MemoryStoredEvent extends ForgeEvent<MemoryStoredPayload> { type: EventType.MEMORY_STORED; } export interface MemoryStoredPayload { memoryId: string; type: MemoryType; confidence: number; } // ─── Error Events ────────────────────────────────────────── export interface ErrorOccurredEvent extends ForgeEvent<ErrorOccurredPayload> { type: EventType.ERROR_OCCURRED; } export interface ErrorOccurredPayload { error: string; stack?: string; source: ErrorSource; severity: ErrorSeverity; recoverable: boolean; phase: PhaseName; agent?: AgentId; }
2.4 Event Creation Helpers
typescript// ─── Event Factory ───────────────────────────────────────── export class EventFactory { static create<T>( type: EventType, source: string, traceId: TraceId, payload: T, options?: EventOptions ): ForgeEvent<T> { return { id: ulid(), traceId, timestamp: new Date(), source, type, payload, phase: options?.phase, cost: options?.cost, duration: options?.duration, metadata: options?.metadata }; } static runStarted( traceId: TraceId, task: string, config: RuntimeConfig ): RunStartedEvent { return EventFactory.create( EventType.RUN_STARTED, 'orchestrator', traceId, { task, config } ) as RunStartedEvent; } static phaseEntered( traceId: TraceId, phase: PhaseName, input: PhaseInput ): PhaseEnteredEvent { return EventFactory.create( EventType.PHASE_ENTERED, 'orchestrator', traceId, { phase, input }, { phase } ) as PhaseEnteredEvent; } static findingDetected( traceId: TraceId, finding: Finding, source: string ): FindingDetectedEvent { return EventFactory.create( EventType.FINDING_DETECTED, source, traceId, { finding, source: source as 'static' | 'security' | 'ai' }, { phase: PhaseName.REVIEW } ) as FindingDetectedEvent; } // ... (add helpers for all common event types) } export interface EventOptions { phase?: PhaseName; cost?: EventCost; duration?: number; metadata?: EventMetadata; }
3. Tool Interface
3.1 Core Tool Interface
typescript// ─── Generic Tool Interface ──────────────────────────────── export interface Tool<TInput = unknown, TOutput = unknown> { /** Tool name (unique identifier) */ name: string; /** Human-readable description */ description: string; /** Zod schemas for input/output validation */ schema: ToolSchema<TInput, TOutput>; /** Execute the tool */ execute(input: TInput, ctx: ToolContext): Promise<ToolResult<TOutput>>; /** Optional: Estimate cost before execution */ estimateCost?(input: TInput): Promise<number>; /** Optional: Validate before execution */ validate?(input: TInput): Promise<ValidationResult>; } // ─── Tool Schema (Zod integration) ───────────────────────── export interface ToolSchema<TInput, TOutput> { input: z.ZodSchema<TInput>; output: z.ZodSchema<TOutput>; /** JSON Schema representation for LLM tool use */ toJSON(): { name: string; description: string; input_schema: JSONSchema; }; } // ─── Tool Context ────────────────────────────────────────── export interface ToolContext { /** Trace ID for this execution */ traceId: TraceId; /** Agent executing this tool */ agent: AgentId; /** Event bus for emitting tool events */ bus: EventBus; /** Logger scoped to this tool */ logger: Logger; /** Configuration */ config: RuntimeConfig; /** Timeout for this tool (ms) */ timeout: number; /** Maximum retries on failure */ maxRetries: number; /** Working directory (for file operations) */ workingDir: string; } // ─── Tool Result Wrapper ─────────────────────────────────── export interface ToolResult<T> { /** Whether execution succeeded */ success: boolean; /** Result data (if successful) */ data?: T; /** Error (if failed) */ error?: ToolError; /** Execution metrics */ metrics: ToolMetrics; /** Warnings (non-fatal issues) */ warnings?: string[]; } export interface ToolError { message: string; code: string; source: ErrorSource; recoverable: boolean; retryable: boolean; stack?: string; } export interface ToolMetrics { /** Duration in milliseconds */ duration: number; /** Tokens used (if LLM tool) */ tokens?: TokenUsage; /** Cost in USD */ cost: number; /** Retry count */ retries: number; /** Additional tool-specific metrics */ custom?: Record<string, number>; }
3.2 Tool Registry
typescript// ─── Tool Registry ───────────────────────────────────────── export interface ToolRegistry { /** Register a tool */ register(tool: Tool): void; /** Get a tool by name */ get(name: string): Tool | undefined; /** List all registered tools */ list(): Tool[]; /** Execute a tool by name */ execute<T, R>( name: string, input: T, ctx: ToolContext ): Promise<ToolResult<R>>; /** Check if tool exists */ has(name: string): boolean; /** Unregister a tool */ unregister(name: string): void; }
3.3 Common Tool Types
typescript// ─── File Operation Tool ─────────────────────────────────── export interface FileOperationTool extends Tool<FileOperationInput, FileOperationOutput> { name: 'read_file' | 'write_file' | 'glob' | 'grep'; } export interface FileOperationInput { path: string; options?: Record<string, unknown>; } export interface FileOperationOutput { content?: string; files?: string[]; matches?: string[]; } // ─── Git Operation Tool ──────────────────────────────────── export interface GitOperationTool extends Tool<GitOperationInput, GitOperationOutput> { name: 'git_diff' | 'git_status' | 'git_commit' | 'git_push'; } export interface GitOperationInput { command: string; args?: string[]; } export interface GitOperationOutput { stdout: string; stderr: string; exitCode: number; } // ─── LLM Tool ────────────────────────────────────────────── export interface LLMTool extends Tool<LLMInput, LLMOutput> { name: 'llm_chat' | 'llm_analyze' | 'llm_generate'; } export interface LLMInput { system?: string; messages: Message[]; temperature?: number; maxTokens?: number; } export interface LLMOutput { content: string; toolCalls?: ToolCall[]; usage: TokenUsage; } // ─── Shell Command Tool ──────────────────────────────────── export interface ShellCommandTool extends Tool<ShellCommandInput, ShellCommandOutput> { name: 'run_command'; } export interface ShellCommandInput { command: string; cwd?: string; env?: Record<string, string>; timeout?: number; } export interface ShellCommandOutput { stdout: string; stderr: string; exitCode: number; signal?: string; }
4. Phase Interface
4.1 Phase Configuration
typescript// ─── Phase Configuration ─────────────────────────────────── export interface Phase { /** Phase name */ name: PhaseName; /** Agent assigned to this phase */ agent: Agent; /** Pre-conditions to enter this phase */ guards: Guard[]; /** Human approval checkpoints */ gates: HumanGate[]; /** Safety circuit breakers */ breakers: CircuitBreaker[]; /** Next phase (null if terminal) */ next: PhaseName | null; /** Maximum iterations for this phase */ maxIterations?: number; /** Maximum cost for this phase (USD) */ maxCost?: number; /** Maximum duration for this phase (ms) */ maxDuration?: number; /** Whether this phase can bounce back to previous */ canBounceBack?: boolean; } // ─── Guard (pre-conditions) ──────────────────────────────── export interface Guard { /** Guard name */ name: string; /** Condition to check */ check(ctx: PhaseContext): Promise<GuardResult>; /** Error message if guard fails */ errorMessage: string; } export interface GuardResult { passed: boolean; reason?: string; } export interface PhaseContext { traceId: TraceId; currentPhase: PhaseName; previousPhases: PhaseName[]; state: Record<string, unknown>; cost: CostTracker; elapsed: number; } // ─── Human Gate ──────────────────────────────────────────── export interface HumanGate { /** Gate ID */ id: string; /** Gate type */ type: HumanGateType; /** Phase this gate is in */ phase: PhaseName; /** Condition for triggering this gate */ condition: GateCondition; /** Prompt to show human */ prompt: string; /** Timeout for human response (ms) */ timeout: number; /** What to do on timeout */ onTimeout: 'fail' | 'approve' | 'reject'; } export enum HumanGateType { ARCHITECTURE_APPROVAL = 'architecture_approval', PRODUCTION_DEPLOY = 'production_deploy', SECURITY_FINDING = 'security_finding', HIGH_RISK_CHANGE = 'high_risk_change', COST_OVERRUN = 'cost_overrun', TEST_FAILURE = 'test_failure' } export type GateCondition = (ctx: PhaseContext, output?: PhaseOutput) => boolean; // ─── Circuit Breaker ─────────────────────────────────────── export interface CircuitBreaker { /** Breaker name */ name: string; /** Type of limit */ type: 'iteration' | 'cost' | 'time' | 'error_rate'; /** Threshold value */ threshold: number; /** Check if breaker should trip */ check(ctx: BreakerContext): boolean; /** What to do when tripped */ onTrip: 'halt' | 'escalate' | 'degrade'; } export interface BreakerContext { iteration?: number; cost?: number; elapsed?: number; errorRate?: number; phase: PhaseName; }
4.2 Pipeline Definition
typescript// ─── Pipeline Definition ─────────────────────────────────── export interface PipelineDefinition { /** Pipeline name */ name: string; /** Phases in order */ phases: Phase[]; /** Initial phase */ startPhase: PhaseName; /** Bounce-back configuration */ bounceConfig: BounceConfig; /** Global limits */ globalLimits: GlobalLimits; } export interface BounceConfig { /** Maximum bounces per phase transition */ maxBounces: number; /** Which phases can bounce back */ allowedBounces: Map<PhaseName, PhaseName>; } export interface GlobalLimits { maxTotalCost: number; // USD maxTotalDuration: number; // ms maxTotalIterations: number; } // ─── Phase Transition ────────────────────────────────────── export interface PhaseTransition { from: PhaseName; to: PhaseName; type: 'forward' | 'bounce' | 'skip'; reason: string; timestamp: Date; }
5. Memory Interface
5.1 Core Memory Interface
typescript// ─── Memory Type Enum ────────────────────────────────────── export enum MemoryType { EPISODIC = 'episodic', // What happened SEMANTIC = 'semantic', // Patterns and facts PROCEDURAL = 'procedural' // How to do things } // ─── Memory Interface ────────────────────────────────────── export interface Memory { /** Memory ID (ULID) */ id: string; /** Memory type */ type: MemoryType; /** Human-readable content */ content: string; /** Context where this memory is relevant */ context: string; /** Embedding for similarity search (stored as Float32Array) */ embedding?: Float32Array; /** Confidence score (0-1, decays without reinforcement) */ confidence: number; /** Source event that created this memory */ source?: string; /** Tags for filtering */ tags: string[]; /** Creation timestamp */ createdAt: Date; /** Last access timestamp */ lastAccessed: Date; /** Access count */ accessCount: number; /** Optional metadata */ metadata?: Record<string, unknown>; } // ─── Memory Storage ──────────────────────────────────────── export interface MemorySystem { /** Store a new memory */ store(memory: CreateMemoryInput): Promise<Memory>; /** Recall memories by similarity */ recall(query: RecallQuery): Promise<Memory[]>; /** Get memory by ID */ get(id: string): Promise<Memory | undefined>; /** Update memory */ update(id: string, updates: Partial<Memory>): Promise<void>; /** Delete memory (archives it) */ delete(id: string): Promise<void>; /** Consolidate memories (merge similar, prune low confidence) */ consolidate(): Promise<ConsolidationResult>; } export interface CreateMemoryInput { type: MemoryType; content: string; context: string; confidence: number; source?: string; tags?: string[]; metadata?: Record<string, unknown>; } export interface RecallQuery { /** Query string or embedding */ query: string | Float32Array; /** Filter by type */ type?: MemoryType; /** Filter by tags */ tags?: string[]; /** Minimum confidence threshold */ minConfidence?: number; /** Maximum results */ limit?: number; /** Similarity threshold (0-1) */ similarityThreshold?: number; } export interface ConsolidationResult { merged: number; pruned: number; promoted: number; // Episodes promoted to semantic archived: number; }
5.2 Embedding Storage
typescript// ─── Embedding in SQLite ─────────────────────────────────── export interface EmbeddingStorage { /** Store embedding as blob */ storeEmbedding(id: string, embedding: Float32Array): Promise<void>; /** Load embedding from blob */ loadEmbedding(id: string): Promise<Float32Array | undefined>; /** Similarity search (cosine similarity) */ similaritySearch( query: Float32Array, limit: number, threshold?: number ): Promise<SimilarityResult[]>; } export interface SimilarityResult { memoryId: string; similarity: number; // Cosine similarity (0-1) memory: Memory; } // ─── Helper Functions ────────────────────────────────────── export function embeddingToBlob(embedding: Float32Array): Buffer { return Buffer.from(embedding.buffer); } export function blobToEmbedding(blob: Buffer): Float32Array { return new Float32Array(blob.buffer); } export function cosineSimilarity(a: Float32Array, b: Float32Array): number { let dotProduct = 0; let normA = 0; let normB = 0; for (let i = 0; i < a.length; i++) { dotProduct += a[i] * b[i]; normA += a[i] * a[i]; normB += b[i] * b[i]; } return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); }
5.3 Memory Confidence and Decay
typescript// ─── Confidence Management ───────────────────────────────── export interface ConfidenceManager { /** Increase confidence (used successfully) */ boost(memoryId: string, amount: number): Promise<void>; /** Decrease confidence (dismissed or failed) */ decay(memoryId: string, amount: number): Promise<void>; /** Apply time-based decay */ applyTimedDecay(): Promise<void>; /** Get confidence score */ getConfidence(memoryId: string): Promise<number>; } // Confidence rules: // - Starts at 0.5 for LLM-extracted learnings // - Starts at 0.7 for human-confirmed learnings // - Starts at 0.9 for production-validated learnings // - +0.1 each time successfully applied // - +0.2 when human confirms // - -0.05 per week without access (decay) // - -0.2 when human dismisses // - Memories below 0.2 are archived
6. Checkpoint Interface
6.1 Checkpoint Structure
typescript// ─── Checkpoint Interface ────────────────────────────────── export interface Checkpoint { /** Checkpoint ID (ULID) */ id: string; /** Trace ID this checkpoint belongs to */ traceId: TraceId; /** Phase when checkpoint was created */ phase: PhaseName; /** Serialized state */ state: CheckpointState; /** Creation timestamp */ timestamp: Date; /** Checkpoint metadata */ metadata: CheckpointMetadata; } export interface CheckpointState { /** Phase outputs so far */ phaseOutputs: Map<PhaseName, PhaseOutput>; /** Working memory state */ workingMemory: unknown; /** Current cost accumulation */ cost: CostSnapshot; /** Phase transitions */ transitions: PhaseTransition[]; /** Bounce count by phase */ bounces: Record<PhaseName, number>; /** Any additional state */ custom?: Record<string, unknown>; } export interface CostSnapshot { total: number; byPhase: Record<PhaseName, number>; tokens: { prompt: number; completion: number; total: number; }; } export interface CheckpointMetadata { version: string; // Checkpoint schema version agent?: AgentId; // Agent that created checkpoint reason?: string; // Why checkpoint was created canRestore: boolean; // Whether this checkpoint is restorable }
6.2 Checkpoint System
typescript// ─── Checkpoint System Interface ─────────────────────────── export interface CheckpointSystem { /** Create a checkpoint */ create( traceId: TraceId, phase: PhaseName, state: CheckpointState, metadata?: Partial<CheckpointMetadata> ): Promise<Checkpoint>; /** List checkpoints for a trace */ list(traceId: TraceId): Promise<Checkpoint[]>; /** Get latest checkpoint */ getLatest(traceId: TraceId): Promise<Checkpoint | undefined>; /** Get checkpoint by ID */ get(id: string): Promise<Checkpoint | undefined>; /** Restore state from checkpoint */ restore(checkpointId: string): Promise<CheckpointState>; /** Delete checkpoint */ delete(checkpointId: string): Promise<void>; /** Prune old checkpoints */ prune(olderThan: Date): Promise<number>; }
6.3 State Reconstruction
typescript// ─── State Reconstruction ────────────────────────────────── export interface StateReconstructor { /** Reconstruct full state from checkpoint */ reconstruct(checkpoint: Checkpoint): Promise<ReconstructedState>; /** Validate checkpoint can be restored */ validate(checkpoint: Checkpoint): Promise<ValidationResult>; /** Diff two checkpoints */ diff(a: Checkpoint, b: Checkpoint): Promise<CheckpointDiff>; } export interface ReconstructedState { /** Current phase */ currentPhase: PhaseName; /** Completed phases */ completedPhases: PhaseName[]; /** Phase outputs */ outputs: Map<PhaseName, PhaseOutput>; /** Cost state */ cost: CostTracker; /** Can resume from here */ canResume: boolean; /** Warnings about reconstruction */ warnings: string[]; } export interface CheckpointDiff { added: string[]; removed: string[]; modified: string[]; phases: { added: PhaseName[]; completed: PhaseName[]; }; costDelta: number; }
7. Supporting Types
7.1 Risk Assessment
typescript// ─── Risk Score ──────────────────────────────────────────── export interface RiskScore { /** Total risk score (0-100) */ total: number; /** Risk level based on total */ level: RiskLevel; /** Component scores */ components: { complexity: number; // 0-20 criticality: number; // 0-20 changeSize: number; // 0-20 testCoverage: number; // 0-20 authorExperience: number; // 0-20 }; /** Factors that contributed to risk */ factors: RiskFactor[]; } export enum RiskLevel { LOW = 'low', // 0-25 MEDIUM = 'medium', // 26-50 HIGH = 'high', // 51-75 CRITICAL = 'critical' // 76-100 } export interface RiskFactor { name: string; weight: number; description: string; }
7.2 Finding
typescript// ─── Finding (from review/test) ──────────────────────────── export interface Finding { /** Finding ID */ id: string; /** Severity level */ severity: Severity; /** Category */ category: FindingCategory; /** Finding message */ message: string; /** File location */ file?: string; /** Line number */ line?: number; /** Column number */ column?: number; /** Confidence in this finding (0-1) */ confidence: number; /** Whether this can be auto-fixed */ fixable: boolean; /** Suggested fix */ suggestedFix?: CodeChange; /** Rule that triggered this */ rule?: string; /** Source analyzer */ source: 'static' | 'security' | 'ai'; } export enum Severity { INFO = 'info', WARNING = 'warning', ERROR = 'error', CRITICAL = 'critical' } export enum FindingCategory { STYLE = 'style', PERFORMANCE = 'performance', SECURITY = 'security', MAINTAINABILITY = 'maintainability', CORRECTNESS = 'correctness', BEST_PRACTICE = 'best_practice' } export interface CodeChange { file: string; before: string; after: string; startLine: number; endLine: number; }
7.3 Error Types
typescript// ─── Error Source ────────────────────────────────────────── export enum ErrorSource { LLM = 'llm', TOOL = 'tool', VALIDATION = 'validation', TIMEOUT = 'timeout', RESOURCE = 'resource', PERMISSION = 'permission', LOGIC = 'logic', NETWORK = 'network', UNKNOWN = 'unknown' } // ─── Error Severity ──────────────────────────────────────── export enum ErrorSeverity { CRITICAL = 'critical', HIGH = 'high', MEDIUM = 'medium', LOW = 'low', WARNING = 'warning' } // ─── Recoverability ──────────────────────────────────────── export enum Recoverability { AUTO = 'auto', MANUAL = 'manual', NONE = 'none', UNKNOWN = 'unknown' } // ─── Forge Error Base ────────────────────────────────────── export class ForgeError extends Error { constructor( message: string, public code: string, public source: ErrorSource, public severity: ErrorSeverity, public recoverable: Recoverability, public context?: Record<string, unknown> ) { super(message); this.name = 'ForgeError'; } } // ─── Specific Error Types ────────────────────────────────── export class CircuitBreakerError extends ForgeError { constructor(message: string, public breaker: string) { super( message, 'CIRCUIT_BREAKER_TRIPPED', ErrorSource.LOGIC, ErrorSeverity.HIGH, Recoverability.MANUAL ); this.name = 'CircuitBreakerError'; } } export class ValidationError extends ForgeError { constructor(message: string, public field?: string) { super( message, 'VALIDATION_FAILED', ErrorSource.VALIDATION, ErrorSeverity.MEDIUM, Recoverability.AUTO ); this.name = 'ValidationError'; } } export class ToolExecutionError extends ForgeError { constructor(message: string, public tool: string) { super( message, 'TOOL_EXECUTION_FAILED', ErrorSource.TOOL, ErrorSeverity.MEDIUM, Recoverability.AUTO ); this.name = 'ToolExecutionError'; } }
7.4 Confidence Score
typescript// ─── Confidence Score ────────────────────────────────────── export type Confidence = number; // 0.0 - 1.0 export const ConfidenceLevel = { VERY_LOW: 0.2, LOW: 0.4, MEDIUM: 0.6, HIGH: 0.8, VERY_HIGH: 0.95 } as const; export function confidenceLabel(score: Confidence): string { if (score < 0.3) return 'very low'; if (score < 0.5) return 'low'; if (score < 0.7) return 'medium'; if (score < 0.9) return 'high'; return 'very high'; }
8. Zod Schemas
8.1 Core Type Validation Schemas
typescriptimport { z } from 'zod'; // ─── Agent Schema ────────────────────────────────────────── export const AgentTypeSchema = z.nativeEnum(AgentType); export const AgentIdSchema = z.string().regex(/^agent:[a-z]+:[A-Z0-9]{26}$/); export const AgentContextSchema = z.object({ traceId: z.string(), sessionId: z.string(), bus: z.any(), // EventBus memory: z.any(), // MemorySystem llm: z.any(), // LLMProvider safety: z.any(), // SafetyControls cost: z.any(), // CostTracker elapsed: z.number().min(0), checkpoint: z.any(), // CheckpointSystem tools: z.any(), // ToolRegistry config: z.any(), // RuntimeConfig logger: z.any() // Logger }); // ─── Phase Schema ────────────────────────────────────────── export const PhaseNameSchema = z.nativeEnum(PhaseName); export const PlanningInputSchema = z.object({ phase: z.literal(PhaseName.PLANNING), task: z.string().min(1), requirements: z.any().optional(), constraints: z.array(z.any()).optional(), context: z.string().optional() }); export const ImplementationInputSchema = z.object({ phase: z.literal(PhaseName.IMPLEMENTATION), plan: z.any(), existingCode: z.any().optional(), fixFindings: z.array(z.any()).optional(), fixFailures: z.array(z.any()).optional() }); // ... (add schemas for all PhaseInput types) export const PhaseInputSchema = z.discriminatedUnion('phase', [ PlanningInputSchema, ImplementationInputSchema, // ... (all phase input schemas) ]); // ─── Event Schema ────────────────────────────────────────── export const EventTypeSchema = z.nativeEnum(EventType); export const ForgeEventSchema = z.object({ id: z.string(), traceId: z.string(), timestamp: z.date(), source: z.string(), type: EventTypeSchema, payload: z.unknown(), phase: PhaseNameSchema.optional(), cost: z.object({ tokens: z.number(), usd: z.number() }).optional(), duration: z.number().optional(), metadata: z.record(z.unknown()).optional() }); // ─── Tool Schema ─────────────────────────────────────────── export const ToolResultSchema = <T extends z.ZodType>(outputSchema: T) => z.object({ success: z.boolean(), data: outputSchema.optional(), error: z.object({ message: z.string(), code: z.string(), source: z.nativeEnum(ErrorSource), recoverable: z.boolean(), retryable: z.boolean(), stack: z.string().optional() }).optional(), metrics: z.object({ duration: z.number(), tokens: z.object({ prompt: z.number(), completion: z.number() }).optional(), cost: z.number(), retries: z.number(), custom: z.record(z.number()).optional() }), warnings: z.array(z.string()).optional() }); // ─── Memory Schema ───────────────────────────────────────── export const MemoryTypeSchema = z.nativeEnum(MemoryType); export const MemorySchema = z.object({ id: z.string(), type: MemoryTypeSchema, content: z.string(), context: z.string(), embedding: z.any().optional(), // Float32Array confidence: z.number().min(0).max(1), source: z.string().optional(), tags: z.array(z.string()), createdAt: z.date(), lastAccessed: z.date(), accessCount: z.number().min(0), metadata: z.record(z.unknown()).optional() }); export const CreateMemoryInputSchema = z.object({ type: MemoryTypeSchema, content: z.string().min(1), context: z.string().min(1), confidence: z.number().min(0).max(1), source: z.string().optional(), tags: z.array(z.string()).optional(), metadata: z.record(z.unknown()).optional() }); // ─── Checkpoint Schema ───────────────────────────────────── export const CheckpointSchema = z.object({ id: z.string(), traceId: z.string(), phase: PhaseNameSchema, state: z.object({ phaseOutputs: z.any(), // Map<PhaseName, PhaseOutput> workingMemory: z.unknown(), cost: z.object({ total: z.number(), byPhase: z.record(z.number()), tokens: z.object({ prompt: z.number(), completion: z.number(), total: z.number() }) }), transitions: z.array(z.any()), bounces: z.record(z.number()), custom: z.record(z.unknown()).optional() }), timestamp: z.date(), metadata: z.object({ version: z.string(), agent: z.string().optional(), reason: z.string().optional(), canRestore: z.boolean() }) }); // ─── Finding Schema ──────────────────────────────────────── export const SeveritySchema = z.nativeEnum(Severity); export const FindingCategorySchema = z.nativeEnum(FindingCategory); export const FindingSchema = z.object({ id: z.string(), severity: SeveritySchema, category: FindingCategorySchema, message: z.string(), file: z.string().optional(), line: z.number().optional(), column: z.number().optional(), confidence: z.number().min(0).max(1), fixable: z.boolean(), suggestedFix: z.object({ file: z.string(), before: z.string(), after: z.string(), startLine: z.number(), endLine: z.number() }).optional(), rule: z.string().optional(), source: z.enum(['static', 'security', 'ai']) }); // ─── Risk Score Schema ───────────────────────────────────── export const RiskLevelSchema = z.nativeEnum(RiskLevel); export const RiskScoreSchema = z.object({ total: z.number().min(0).max(100), level: RiskLevelSchema, components: z.object({ complexity: z.number().min(0).max(20), criticality: z.number().min(0).max(20), changeSize: z.number().min(0).max(20), testCoverage: z.number().min(0).max(20), authorExperience: z.number().min(0).max(20) }), factors: z.array(z.object({ name: z.string(), weight: z.number(), description: z.string() })) });
8.2 Validation Helpers
typescript// ─── Validation Helpers ──────────────────────────────────── export function validatePhaseInput(input: unknown): PhaseInput { return PhaseInputSchema.parse(input); } export function validateForgeEvent(event: unknown): ForgeEvent { return ForgeEventSchema.parse(event); } export function validateMemory(memory: unknown): Memory { return MemorySchema.parse(memory); } export function validateCheckpoint(checkpoint: unknown): Checkpoint { return CheckpointSchema.parse(checkpoint); } export function validateFinding(finding: unknown): Finding { return FindingSchema.parse(finding); } // ─── Safe Parse (returns result) ─────────────────────────── export function safeValidatePhaseInput(input: unknown) { return PhaseInputSchema.safeParse(input); } export function safeValidateMemory(memory: unknown) { return MemorySchema.safeParse(memory); } // ─── Type Guards ─────────────────────────────────────────── export function isPhaseInput(value: unknown): value is PhaseInput { return PhaseInputSchema.safeParse(value).success; } export function isForgeEvent(value: unknown): value is ForgeEvent { return ForgeEventSchema.safeParse(value).success; } export function isMemory(value: unknown): value is Memory { return MemorySchema.safeParse(value).success; } export function isCheckpoint(value: unknown): value is Checkpoint { return CheckpointSchema.safeParse(value).success; }
9. Type Guards
9.1 Runtime Type Narrowing
typescript// ─── Agent Type Guards ───────────────────────────────────── export function isAgent(value: unknown): value is Agent { return ( typeof value === 'object' && value !== null && 'id' in value && 'type' in value && 'execute' in value && typeof (value as any).execute === 'function' ); } export function isPlannerAgent(agent: Agent): agent is Agent<PlanningInput, PlanningOutput> { return agent.type === AgentType.PLANNER; } export function isImplementerAgent(agent: Agent): agent is Agent<ImplementationInput, ImplementationOutput> { return agent.type === AgentType.IMPLEMENTER; } // ─── Phase Type Guards ───────────────────────────────────── export function isPlanningInput(input: PhaseInput): input is PlanningInput { return input.phase === PhaseName.PLANNING; } export function isImplementationInput(input: PhaseInput): input is ImplementationInput { return input.phase === PhaseName.IMPLEMENTATION; } export function isReviewInput(input: PhaseInput): input is ReviewInput { return input.phase === PhaseName.REVIEW; } export function isPlanningOutput(output: PhaseOutput): output is PlanningOutput { return output.phase === PhaseName.PLANNING; } // ─── Event Type Guards ───────────────────────────────────── export function isRunStartedEvent(event: ForgeEvent): event is RunStartedEvent { return event.type === EventType.RUN_STARTED; } export function isPhaseCompletedEvent(event: ForgeEvent): event is PhaseCompletedEvent { return event.type === EventType.PHASE_COMPLETED; } export function isFindingDetectedEvent(event: ForgeEvent): event is FindingDetectedEvent { return event.type === EventType.FINDING_DETECTED; } export function isBreakerTrippedEvent(event: ForgeEvent): event is BreakerTrippedEvent { return event.type === EventType.BREAKER_TRIPPED; } // ─── Tool Type Guards ────────────────────────────────────── export function isTool(value: unknown): value is Tool { return ( typeof value === 'object' && value !== null && 'name' in value && 'description' in value && 'schema' in value && 'execute' in value && typeof (value as any).execute === 'function' ); } export function isToolResult<T>(value: unknown): value is ToolResult<T> { return ( typeof value === 'object' && value !== null && 'success' in value && typeof (value as any).success === 'boolean' && 'metrics' in value ); } // ─── Memory Type Guards ──────────────────────────────────── export function isEpisodicMemory(memory: Memory): boolean { return memory.type === MemoryType.EPISODIC; } export function isSemanticMemory(memory: Memory): boolean { return memory.type === MemoryType.SEMANTIC; } export function isProceduralMemory(memory: Memory): boolean { return memory.type === MemoryType.PROCEDURAL; } // ─── Error Type Guards ───────────────────────────────────── export function isForgeError(error: unknown): error is ForgeError { return error instanceof ForgeError; } export function isCircuitBreakerError(error: unknown): error is CircuitBreakerError { return error instanceof CircuitBreakerError; } export function isToolExecutionError(error: unknown): error is ToolExecutionError { return error instanceof ToolExecutionError; } // ─── Risk Level Guards ───────────────────────────────────── export function isHighRisk(riskScore: RiskScore): boolean { return riskScore.level === RiskLevel.HIGH || riskScore.level === RiskLevel.CRITICAL; } export function isCriticalRisk(riskScore: RiskScore): boolean { return riskScore.level === RiskLevel.CRITICAL; } // ─── Finding Guards ──────────────────────────────────────── export function isCriticalFinding(finding: Finding): boolean { return finding.severity === Severity.CRITICAL; } export function isSecurityFinding(finding: Finding): boolean { return finding.category === FindingCategory.SECURITY; }
10. File Organization
10.1 Directory Structure
src/core/
├── types.ts # All core types (Agent, Event, Tool, Phase, Memory, Checkpoint)
├── schemas.ts # All Zod schemas and validation helpers
├── guards.ts # All type guard functions
├── errors.ts # Error classes and error handling utilities
├── constants.ts # Constants and default values
├── utils.ts # Utility functions (embedding helpers, etc.)
└── index.ts # Public exports
10.2 What Goes in Each File
types.ts (Main Type Definitions)
- All interfaces and types
- Enums
- Type aliases
- Generic type definitions
- NO implementations, only type definitions
schemas.ts (Runtime Validation)
- All Zod schemas
- Validation helper functions
- Safe parse wrappers
- Schema-to-JSON converters
guards.ts (Type Narrowing)
- Type guard functions (is*, assert*)
- Runtime type checking
- Discriminated union helpers
errors.ts (Error Taxonomy)
- Error base classes
- Specific error types
- Error factory functions
- Error serialization
constants.ts (Default Values)
- Default configuration
- Magic numbers
- Enums that are truly constant
- System limits
utils.ts (Helper Functions)
- Embedding conversions
- ID generation (ulid)
- Similarity calculations
- Other pure utility functions
index.ts (Public API)
typescript// Re-export everything that should be public export * from './types'; export * from './schemas'; export * from './guards'; export * from './errors'; export * from './constants'; export * from './utils'; // Grouped exports for convenience export * as Types from './types'; export * as Schemas from './schemas'; export * as Guards from './guards'; export * as Errors from './errors';
11. Implementation Checklist
Phase 1: Core Types (Week 1, Day 1-2)
- Create
src/core/types.ts - Define all 6 core interfaces (Agent, ForgeEvent, Tool, Phase, Memory, Checkpoint)
- Define all enums (AgentType, PhaseName, EventType, MemoryType, etc.)
- Define PhaseInput/PhaseOutput discriminated unions
- Define all supporting types (RiskScore, Finding, etc.)
- Add comprehensive JSDoc comments
Phase 2: Schemas (Week 1, Day 3)
- Create
src/core/schemas.ts - Define Zod schemas for all core types
- Create validation helper functions
- Create safe parse wrappers
- Add schema-to-JSON converters for LLM tool use
Phase 3: Type Guards (Week 1, Day 4)
- Create
src/core/guards.ts - Implement type guards for all core types
- Implement discriminated union helpers
- Add utility guards (isHighRisk, isCriticalFinding, etc.)
Phase 4: Errors (Week 1, Day 5)
- Create
src/core/errors.ts - Implement ForgeError base class
- Implement specific error types
- Add error factory functions
- Add error serialization utilities
Phase 5: Supporting Files (Week 1, Day 6)
- Create
src/core/constants.tswith defaults - Create
src/core/utils.tswith helpers - Create
src/core/index.tswith exports - Add comprehensive README in
src/core/
Phase 6: Testing (Week 1, Day 7)
- Create
src/core/__tests__/types.test.ts - Test all Zod schemas
- Test all type guards
- Test error creation and serialization
- Test utility functions
- Achieve 100% test coverage
12. Testing Strategy
12.1 Schema Validation Tests
typescriptimport { describe, test, expect } from 'bun:test'; import { PhaseInputSchema, validatePhaseInput } from '../schemas'; describe('PhaseInput Schema', () => { test('validates PlanningInput', () => { const input = { phase: 'planning', task: 'Implement user auth' }; expect(() => validatePhaseInput(input)).not.toThrow(); }); test('rejects invalid phase', () => { const input = { phase: 'invalid', task: 'Test' }; expect(() => validatePhaseInput(input)).toThrow(); }); test('rejects missing required fields', () => { const input = { phase: 'planning' // Missing task }; expect(() => validatePhaseInput(input)).toThrow(); }); });
12.2 Type Guard Tests
typescriptimport { describe, test, expect } from 'bun:test'; import { isAgent, isPlanningInput } from '../guards'; describe('Type Guards', () => { test('isAgent identifies valid agent', () => { const agent = { id: 'agent:planner:01234567890ABCDEFGHIJKLMN', type: 'planner', execute: async () => ({}) }; expect(isAgent(agent)).toBe(true); }); test('isPlanningInput narrows union type', () => { const input = { phase: 'planning', task: 'Test task' }; if (isPlanningInput(input)) { // TypeScript knows input.task exists here expect(input.task).toBe('Test task'); } }); });
12.3 Error Tests
typescriptimport { describe, test, expect } from 'bun:test'; import { CircuitBreakerError, ErrorSource, ErrorSeverity } from '../errors'; describe('Errors', () => { test('CircuitBreakerError contains correct metadata', () => { const error = new CircuitBreakerError('Too many iterations', 'iteration_limit'); expect(error.name).toBe('CircuitBreakerError'); expect(error.code).toBe('CIRCUIT_BREAKER_TRIPPED'); expect(error.source).toBe(ErrorSource.LOGIC); expect(error.severity).toBe(ErrorSeverity.HIGH); expect(error.breaker).toBe('iteration_limit'); }); });
13. Documentation Requirements
13.1 JSDoc Comments
Every type, interface, and enum must have JSDoc comments:
typescript/** * Agent represents an autonomous entity in the Forge system. * Agents follow the perceive-reason-act-learn loop pattern. * * @template TInput - The input type for this agent's execute method * @template TOutput - The output type for this agent's execute method * * @example * ```typescript * class PlannerAgent implements Agent<PlanningInput, PlanningOutput> { * async execute(input, ctx) { * // Implementation * } * } * ``` */ export interface Agent<TInput = PhaseInput, TOutput = PhaseOutput> { // ... }
13.2 README.md in src/core/
Create comprehensive documentation:
markdown# Core Abstractions This directory contains the foundational types for the Forge system. ## Type Hierarchy - **Agent**: Autonomous execution units - **ForgeEvent**: All system events - **Tool**: External capabilities - **Phase**: Pipeline stages - **Memory**: Learning storage - **Checkpoint**: State persistence ## Usage ```typescript import { Agent, PhaseInput, AgentContext } from '@/core'; class MyAgent implements Agent { async execute(input: PhaseInput, ctx: AgentContext) { // Implementation } }
Design Principles
- Type Safety: Everything is typed with TypeScript strict mode
- Runtime Validation: Zod schemas validate at runtime
- Discriminated Unions: Phase inputs/outputs use discriminated unions
- Immutability: Core types are immutable by design
See Also
- SYSTEM-DESIGN.md Section 3 for architectural context
- Implementation plan: plans/03-core-abstractions.md
---
## 14. Dependencies
### 14.1 Required Packages
```json
{
"dependencies": {
"zod": "^3.22.4",
"ulid": "^2.3.0"
},
"devDependencies": {
"bun-types": "latest"
}
}
14.2 No External Dependencies
Core abstractions should have ZERO external dependencies beyond:
- Zod (for runtime validation)
- ulid (for ID generation)
- Standard TypeScript/Bun types
15. Next Steps After Completion
Once core abstractions are complete:
- Week 2: Implement Event Bus (
src/core/bus.ts) - Week 2: Implement Configuration (
src/core/config.ts) - Week 2: Implement Memory Store (
src/memory/store.ts) - Week 3: Implement Base Agent (
src/agents/base.ts)
The core types are the foundation. Everything else composes these types.
Acceptance Criteria
This implementation is complete when:
- All 6 core types are fully defined with comprehensive TypeScript types
- All PhaseInput/PhaseOutput types are defined with discriminated unions
- All ~40 EventType enums are defined with typed payloads
- Complete Zod schemas for runtime validation exist
- Type guards for all core types exist
- Error taxonomy is complete with base classes
- Test coverage is 100%
- Documentation is comprehensive with JSDoc and README
- No linter errors or type errors
- Can import and use types in other modules without issues
Definition of Done: Another developer can import these types and build agents, tools, and phases without needing to modify or extend the core types.