Skip to content

feat: sd graph / sd triage — PageRank + betweenness centrality on the dependency graph #6

@RogerNavelsaker

Description

@RogerNavelsaker

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions