Problem
sd ready surfaces unblocked issues but treats all of them as equivalent. In practice the dependency graph has structure worth exploiting:
- Some issues are bottlenecks — many other issues depend on them transitively. Unblocking them opens up the most parallel work.
- Some issues are on the critical path — they have the longest chain of dependent work after them.
- Some issues are parallelizable leaves — no one depends on them, safe to do in any order.
An agent picking randomly from sd ready output may spend cycles on a leaf while a bottleneck sits unstarted.
Proposal
Seeds already stores the full dep graph bidirectionally (blockedBy / blocks). Add a graph analysis command that computes topology metrics and ranks work accordingly.
sd graph
Human-readable graph overview:
sd graph # full graph summary: bottlenecks, critical path, parallelizable leaves
sd graph --critical-path # show the longest dependency chain
sd graph --bottlenecks # issues with highest betweenness centrality
sd graph --dot # emit Graphviz DOT for visualization
sd triage
Agent-facing ranked work list (machine-readable counterpart to sd ready):
sd triage # ranked ready issues: bottlenecks first, leaves last
sd triage --json # JSON output for agent consumption
sd triage --limit <n> # top N issues to work on now
JSON shape (for --json):
{
"issues": [
{
"id": "proj-a1b2",
"title": "...",
"pagerank": 0.18,
"betweenness": 0.42,
"criticalPathLength": 5,
"score": 0.87
}
]
}
Algorithms
Both commands run on the same graph built from all issues' blockedBy/blocks edges:
PageRank — iterative importance score. Issues that many others depend on (directly or transitively) get higher scores. Identifies work that unblocks the most downstream issues.
Betweenness centrality — fraction of shortest paths between any two nodes that pass through this node. High betweenness = coordination bottleneck. Resolving it reduces sequential pressure.
Critical path length — longest chain of blocks edges from this node forward. Issues with long forward chains should start earliest.
Composite score — weighted combination of the three, tunable via config or flag. Default: 0.5 * pagerank + 0.3 * betweenness + 0.2 * normalizedCriticalPath.
Why in seeds (not in overstory or a separate tool)
Seeds owns the dep graph. The JSONL storage and bidirectional edge model already have everything needed. Adding graph analysis here keeps the analysis co-located with the data and means any project using seeds gets graph-aware routing without additional tooling. The implementation is ~100–150 lines of pure TypeScript — no external graph library needed for these algorithms at this scale.
Relationship to sd ready
sd ready stays as-is: a fast topological filter for human use. sd triage is the agent-facing, graph-aware complement — same eligibility check, ranked output.
Context
Filed from discussion on overstory#133 about completing the Plan → Trellis → Seeds → Code workflow. Graph-aware routing is the missing piece that prevents agents from randomly sequencing equivalent-priority work when the dependency structure implies a better order.
Problem
sd readysurfaces unblocked issues but treats all of them as equivalent. In practice the dependency graph has structure worth exploiting:An agent picking randomly from
sd readyoutput may spend cycles on a leaf while a bottleneck sits unstarted.Proposal
Seeds already stores the full dep graph bidirectionally (
blockedBy/blocks). Add a graph analysis command that computes topology metrics and ranks work accordingly.sd graphHuman-readable graph overview:
sd triageAgent-facing ranked work list (machine-readable counterpart to
sd ready):JSON shape (for
--json):{ "issues": [ { "id": "proj-a1b2", "title": "...", "pagerank": 0.18, "betweenness": 0.42, "criticalPathLength": 5, "score": 0.87 } ] }Algorithms
Both commands run on the same graph built from all issues'
blockedBy/blocksedges:PageRank — iterative importance score. Issues that many others depend on (directly or transitively) get higher scores. Identifies work that unblocks the most downstream issues.
Betweenness centrality — fraction of shortest paths between any two nodes that pass through this node. High betweenness = coordination bottleneck. Resolving it reduces sequential pressure.
Critical path length — longest chain of
blocksedges from this node forward. Issues with long forward chains should start earliest.Composite score — weighted combination of the three, tunable via config or flag. Default:
0.5 * pagerank + 0.3 * betweenness + 0.2 * normalizedCriticalPath.Why in seeds (not in overstory or a separate tool)
Seeds owns the dep graph. The JSONL storage and bidirectional edge model already have everything needed. Adding graph analysis here keeps the analysis co-located with the data and means any project using seeds gets graph-aware routing without additional tooling. The implementation is ~100–150 lines of pure TypeScript — no external graph library needed for these algorithms at this scale.
Relationship to
sd readysd readystays as-is: a fast topological filter for human use.sd triageis the agent-facing, graph-aware complement — same eligibility check, ranked output.Context
Filed from discussion on overstory#133 about completing the Plan → Trellis → Seeds → Code workflow. Graph-aware routing is the missing piece that prevents agents from randomly sequencing equivalent-priority work when the dependency structure implies a better order.