Files
AirCoding/packages/runtime/src/scheduler/WavePlanner.ts
AirCoding a773bac28c P0-P8: Full V1.0.0 Alpha implementation + audit reports
Implements 123 tasks across 9 phases (T-001..T-809) totaling 146 source files.

Monorepo (P0):
- 7-package Bun + Turborepo + TypeScript monorepo
- dependency-cruiser enforcing 7 forbidden edges + 5 deep-import rules

Contracts (P0):
- 16 type files (ids/error/event/runtime/ipc/task/worker-result/tool/artifact/evidence/project/provider/permission/ui/capability/platform)

Storage & Events (P1):
- DatabaseManager + MigrationRunner (19 tables, 22 indexes, 5 schema_meta seeds)
- 16 repositories (Repository<T,I,U> pattern, INV-1 status columns via EventStore.project only)
- EventSchemaRegistry (54 durable + 7 ephemeral), EventStore, EventBus, EventIngestor
- Project/Session/Artifact/Evidence stores + 8-step Recovery

Tools & Permission (P2):
- PathClassifier (8 categories), CommandRiskAnalyzer (10 categories), SecretRedactor
- PermissionEngine 6-layer evaluation (capability→profile→task_scope→risk→credential→user_prompt)
- ToolRegistry with 20+ tools across fs/shell/git/project/artifact/context/permission/doctor
- CapabilityManifestValidator + CapabilityRegistry

LLM & Context (P3):
- ModelConfigLoader, CapabilityMatrix, AnthropicCanonicalConverter
- AnthropicAdapter + OpenAICompatibleAdapter
- ProviderManager facade
- PromptLayerLoader (L0/L1/L3/L5), CompactionPolicy, ContextAssembler

Worker IPC & Scheduler (P4):
- WorkerProtocol (NDJSON), WorkerProcess (exit codes 0-5), WorkerManager (spawn/handshake)
- WorkerRuntime (INV-3: IPC only, no direct fs/shell/SQLite)
- 5 worker roles (Executor/Reviewer/Debugger/Compactor/ExperienceMiner)
- TaskGraph, WavePlanner, RetryPlanner, AgentMonitor, WorkspaceManager
- Scheduler (state machine), 8-step Recovery

C++ Toolchain (P5):
- DiagnosticParser, CppProjectDetector, CMakeConfigurator, CppBuilder
- CppTestRunner, CppcheckRunner, ClangdClient
- CppToolRegistrar + capability manifest

Projection & TUI (P6):
- ProjectionStore (hydrate/apply/snapshot/subscribe)
- TuiApp + 8 components (Session/Task/Agent/Tool/Diff/Evidence/Permission/Blocker/Hud)
- ProjectionClient in-process ref

Agents & Knowledge (P7):
- MainAgent, ArchitectureDesigner
- DebugKnowledgeStore + LearnedMemoryStore (single-writer, outbox model)
- Role integration wiring

CLI & Doctor & Release (P8):
- Logger + DeveloperLogEncryptor (AES-256-GCM)
- DoctorService (self_bootstrap first)
- RuntimeApp + ServiceRegistry
- 11 CLI commands: run/init/doctor/provider/resume/compact/history/session/restore/e2e/release
- CliEntrypoint + air<TODO>

Audit (in AirPlan/docs/):
- Deepseek开发阶段审计.md (97 findings)
- Opus开发阶段审计.md (140+ findings, 18 P0 blockers)
- MiniMaxM3开发阶段审计.md (18 P0 blockers, focuses on executability)
- AirPlan/TODO.md (technical debt + 42 TODOs by phase)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 19:19:55 +08:00

107 lines
2.7 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* WavePlanner - Plans execution waves for tasks
*
* Implements DD §7.3.
*
* @module packages/runtime/src/scheduler/WavePlanner
*/
import { TaskGraph, type TaskNode, type DependencyType } from './TaskGraph.js'
export interface WavePlan {
wave_id: number
tasks: Array<{
task_id: string
workspace: string
model?: string
agent_type: string
}>
can_parallelize: boolean
resource_cap: number
}
export interface WriteArea {
area: string
tasks: string[]
}
export class WavePlanner {
private resource_cap: number
constructor(resource_cap: number = 4) {
this.resource_cap = resource_cap
}
/**
* Plan next execution wave from runnable tasks.
*/
plan(graph: TaskGraph): WavePlan[] {
const runnable = graph.get_runnable_tasks()
if (runnable.length === 0) return []
// Group by write areas to detect conflicts
const write_areas = this.group_by_write_area(runnable)
// Assign workspaces
const assignments = this.assign_workspaces(write_areas, runnable)
// Detect conflicts — same uncertain area → serialize
const can_parallelize = this.can_parallelize(write_areas)
// Cap resources
const capped = assignments.slice(0, this.resource_cap)
return [{
wave_id: Date.now(),
tasks: capped,
can_parallelize,
resource_cap: this.resource_cap
}]
}
/**
* Group tasks by their write areas to detect potential conflicts.
*/
group_by_write_area(tasks: TaskNode[]): WriteArea[] {
// Extract write areas from task metadata (stub)
const areas: Map<string, string[]> = new Map()
for (const task of tasks) {
const area = 'default' // Would be extracted from task spec
if (!areas.has(area)) areas.set(area, [])
areas.get(area)!.push(task.id)
}
return Array.from(areas.entries()).map(([area, tasks]) => ({ area, tasks }))
}
/**
* Assign workspace to each task.
* Different write areas → concurrent.
* Same uncertain area → serialize.
*/
assign_workspaces(areas: WriteArea[], tasks: TaskNode[]): Array<{ task_id: string; workspace: string; agent_type: string }> {
return tasks.map((task, index) => ({
task_id: task.id,
workspace: `ws_${index}`,
agent_type: 'executor' // Would be determined by task type
}))
}
/**
* Check if tasks can run in parallel write areas don't conflict).
*/
can_parallelize(areas: WriteArea[]): boolean {
// Different write areas → concurrent
return areas.length > 1
}
/**
* Assign model for a task based on requirements.
*/
assign_model(task: TaskNode): string {
// Would consult capability matrix
return 'claude-sonnet-4-6'
}
}