import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts"; // Define the Linked Data structures interface JsonLdNode { "@context"?: string; "@type": string; "@id": string; name: string; description?: string; satisfies?: string[]; // IDs of other nodes this node fulfills/relates to } // Mock embedded JSON-LD blocks (normally these would be extracted from the frontmatter of Markdown files) const mockReq1: JsonLdNode = { "@context": "https://schema.org", "@type": "BusinessRequirement", "@id": "REQ-001", name: "User Authentication", description: "The system must authenticate users securely." }; const mockTask1: JsonLdNode = { "@context": "https://schema.org", "@type": "EngineeringTask", "@id": "urn:uuid:018f6c3a-1234-7890-abcd-ef0123456789", name: "Implement Login Endpoint", satisfies: ["REQ-001"] // This links the technical task to the business requirement }; const mockTest1: JsonLdNode = { "@context": "https://schema.org", "@type": "TestCase", "@id": "TEST-AUTH-01", name: "Test invalid passwords return 401", satisfies: ["urn:uuid:018f6c3a-1234-7890-abcd-ef0123456789"] // This links the test to the task }; /** * Builds a simple adjacency list representing the ontology graph. */ function buildOntologyGraph(nodes: JsonLdNode[]): Map { const graph = new Map(); // Initialize all nodes for (const node of nodes) { if (!graph.has(node["@id"])) { graph.set(node["@id"], []); } } // Map edges (satisfies) -> Note: doing a reverse mapping here (A satisfies B means B is dependent on A) // For traceability, we want to look at a Requirement and ask "What implements this?" for (const node of nodes) { if (node.satisfies) { for (const targetId of node.satisfies) { if (!graph.has(targetId)) { graph.set(targetId, []); // Create the node if it doesn't exist } // Link the target ID to the node that satisfies it graph.get(targetId)!.push(node["@id"]); } } } return graph; } /** * Recursively find all technical artifacts that trace back to a specific requirement. */ function traceRequirement(graph: Map, startId: string): string[] { const visited = new Set(); const stack = [startId]; while (stack.length > 0) { const current = stack.pop()!; if (!visited.has(current)) { visited.add(current); const edges = graph.get(current) || []; for (const edge of edges) { stack.push(edge); } } } return Array.from(visited); } async function runOntologyPoC() { console.log("--- Agent Forum: Ontology & Traceability PoC ---"); const allNodes = [mockReq1, mockTask1, mockTest1]; console.log(`Parsed ${allNodes.length} JSON-LD blocks from mock repository.`); // Build the graph const graph = buildOntologyGraph(allNodes); console.log("\nGenerated Ontology Graph (Adjacency List):"); for (const [id, edges] of graph.entries()) { console.log(` ${id} is satisfied by: [${edges.join(", ")}]`); } // Trace the requirement console.log(`\nTracing impact for Business Requirement: ${mockReq1["@id"]}...`); const traceResults = traceRequirement(graph, mockReq1["@id"]); console.log(`Artifacts tracing back to ${mockReq1["@id"]}:`, traceResults); assert(traceResults.includes(mockTask1["@id"]), "Graph failed to link Task to Requirement"); assert(traceResults.includes(mockTest1["@id"]), "Graph failed to link Test to Task and up to Requirement"); console.log("\nPoC Successful: Deep traceability achieved via mathematical graph traversal."); } if (import.meta.main) { runOntologyPoC().catch(err => { console.error("PoC Failed:", err); Deno.exit(1); }); }