feat(analysis/critical-path): implement criticalPath and weightedCriticalPath
Implement longest-path-in-DAG algorithms using topological order + dynamic programming.
- criticalPath(graph): finds unweighted longest path (each node = weight 1)
- weightedCriticalPath(graph, weightFn): finds path with highest cumulative weight
- Both throw CircularDependencyError on cyclic graphs
- Empty graph returns [], single-node graph returns [nodeId]
- 20 unit tests covering linear chains, diamonds, weighted variants, cyclic detection