import { assertEquals } from "https://deno.land/std@0.224.0/testing/asserts.ts"; import { parse } from "https://deno.land/std@0.224.0/yaml/mod.ts"; /** * Proof of Concept: Semantic Task DAG Engine * * This module demonstrates how we can parse a strict YAML Directed Acyclic Graph (DAG) * of tasks to calculate the critical path and ensure agents are only ever handed * explicitly unblocked tasks. */ export interface TaskNode { id: string; title: string; blocked_by: string[]; status: "pending" | "in-progress" | "complete"; } export class TaskDAG { private nodes: Map = new Map(); constructor(yamlContent: string) { const rawNodes = parse(yamlContent) as TaskNode[]; for (const node of rawNodes) { this.nodes.set(node.id, { ...node, blocked_by: node.blocked_by || [], status: node.status || "pending", }); } } /** * Returns a list of tasks that are fully unblocked and ready to be worked on. */ getUnblockedTasks(): TaskNode[] { const unblocked: TaskNode[] = []; for (const node of this.nodes.values()) { if (node.status === "complete") continue; const isBlocked = node.blocked_by.some( (depId) => this.nodes.get(depId)?.status !== "complete", ); if (!isBlocked) { unblocked.push(node); } } return unblocked; } markComplete(taskId: string) { const node = this.nodes.get(taskId); if (node) { node.status = "complete"; } } } // In a real scenario, tests would be separated. For this PoC, we will run the tests here. if (import.meta.main) { console.log("Running DAG Engine PoC tests..."); const yamlInput = ` - id: task_1 title: Setup Git Notes PoC status: complete - id: task_2 title: Setup DAG Engine PoC blocked_by: [task_1] status: pending - id: task_3 title: Setup Local Intelligence PoC blocked_by: [task_1, task_2] status: pending - id: task_4 title: Write Assessment Report blocked_by: [task_1] status: pending `; try { const dag = new TaskDAG(yamlInput); // Initially, task_2 and task_4 should be unblocked because task_1 is complete. let unblocked = dag.getUnblockedTasks(); assertEquals(unblocked.length, 2); assertEquals(unblocked[0].id, "task_2"); assertEquals(unblocked[1].id, "task_4"); // Mark task_2 as complete. Now task_3 should still be blocked because task_4 has no effect, // wait, task_3 is blocked by task_1 and task_2. Since both will be complete, task_3 should unlock. dag.markComplete("task_2"); unblocked = dag.getUnblockedTasks(); // Unblocked should now be task_3 and task_4 assertEquals(unblocked.length, 2); assertEquals(unblocked.find((t) => t.id === "task_3")?.id, "task_3"); assertEquals(unblocked.find((t) => t.id === "task_4")?.id, "task_4"); console.log( "✅ DAG Engine PoC successful: Correctly calculated unblocked tasks.", ); } catch (err) { console.error("❌ DAG Engine PoC failed:", err); } }