okf-gem · docs
CLI · read

okf graph

The raw structure: nodes, edges, indexes.

When to use it

  • To feed the bundle's structure into your own analysis: centrality, clustering, dead-end detection, anything the built-in views do not compute.
  • To plan a traversal before consuming a large bundle: pull the minimal graph, pick the hubs, then read only the concepts on the path.
  • When you want the structure the interactive server visualizes, but as data. For the visual version, see okf server.
  • To rank the hubs or weigh the directories without computing it yourself: --hubs ranks concepts by inbound links, --traffic reads cohesion against coupling one directory at a time. Both make the refine playbook's structural judgements mechanical.

How it works

graph builds the node and edge graph from every concept that parses. Plain text prints just the totals; the substance is in --json, which emits a machine-readable dump: nodes with id, type, title, description, and tags, plus edges. Two flags trim the payload: --no-body drops each node's body, and --minimal ships only id and title per node plus the type and tag indexes, the lean shape the server page boots from.

Like the server, graph is best-effort under section 9: a file with invalid frontmatter is skipped and noted on stderr, never fatal, so one bad file cannot break the dump. The graph server page covers how the same graph drives the browser view.

Two aggregate reads answer structural questions the raw dump would make you compute. --hubs ranks every concept that has at least one inbound link by inbound degree, and groups each hub's inbound links by the directory they come from (core/status ×3 flows 2, billing 1). A hub whose inbound majority is foreign to its own directory is a move candidate, which is the refine playbook's origin test made mechanical. JSON: { bundle, count, hubs: [{ id, top_dir, inbound, by_top_dir }] }.

--traffic reads the graph one grain coarser, by directory rather than concept: it collapses each concept into its directory and the links between two directories into one weighted arc, then reports internal, out, and in traffic per directory with a cohesion, its internal share of that total. Rows sort by cohesion ascending, so the directories with a case to answer come first: near-zero cohesion under heavy inbound is a shared vocabulary doing its job, heavy outbound with nothing back is a projection wearing a directory, and a directory with no traffic prints a dash rather than a 0% it did not earn. The arc cut is fitted to the bundle rather than fixed, and --cut N overrides it; cohesion is computed over every arc regardless, so narrowing the drawn picture never moves the evidence. JSON: { bundle, cut, fitted, dirs, arcs, total_arcs }.

Try it

okf graph docs/
37 concepts, 87 links
okf graph docs/ --minimal --json

emits { nodes: [{ id, title }], edges, types, tags } as compact single-line JSON (the type and tag indexes ride along only with --minimal); the full okf graph docs/ --json emits { nodes: [{ id, type, title, description, tags, body }], edges }. Add --pretty to indent either for reading.

Weigh the directories to ask whether each is a concern or a container:

okf graph docs/ --traffic
Traffic - docs (4 dirs, 9 of 14 arcs at weight 2 or more)

  Dir      Concepts  Internal   Out    In  Cohesion
  guides          3         0     8     2        0%
  cli            15         9    11     9       31%
  skill           9         7     6     8       35%
  (root)          3         2     1     3        40%

guides at 0% cohesion with links only outward is a container, files grouped by what they are for; skill at 35%, its concepts mostly citing one another, is a concern. Rank the hubs instead with okf graph docs/ --hubs.

Pitfalls

  • The plain-text view is only a summary. Two numbers, nothing else; without --json there is no structure to pipe anywhere.
  • The full dump carries every body. On a large bundle that is by far the biggest share of the payload; reach for --no-body or --minimal unless you actually need the prose.
  • Best-effort means silently smaller, loudly noted. Skipped files shrink the graph and the note goes to stderr, so a pipeline reading stdout will not see it. Gate on okf validate first if completeness matters.
  • --hubs and --traffic are aggregates, not the graph. They summarize the same edges the dump carries; when you need the raw nodes and edges, reach for --json. And --traffic's --cut only narrows what is drawn, since cohesion is computed over every arc, so a tighter cut never changes the numbers.
esc
navigate open