ADR-0033: Select interactive graph presentation at the CLI boundary while preserving piped DOT
| Field | Value |
|---|---|
| Status | accepted |
| Date | 2026-08-26 |
| Review by | 2027-02-26 |
| Schema version | 0.1.0 |
| Reversibility | two-way-door |
| Blast radius | org |
| Scope | org |
| Tags | cli, graph, visualization, compatibility, determinism |
| Deciders | @mbeacom |
| Authored by | agent-drafted |
| Ratified by | @mbeacom |
| Review tier | arb |
| Review reason | Changes the documented default-selection policy of a published CLI command while preserving its machine channels and adding public core renderers. |
| Relates to | 0001, 0004, 0007, 0010, 0014, 0016, 0031 |
| Affects | path:packages/core/src/graph/**, path:packages/cli/src/graph.ts, path:packages/cli/src/index.ts, path:packages/cli/src/command-registry.ts, path:site/src/content/docs/** |
| Source | docs/adr/0033-select-interactive-graph-presentation-at-the-cli-boundary-while-preserving-piped-dot.md |
Status: accepted. Agent-drafted and ratified by
@mbeacomon 2026-08-26. This supersedes the Phase 0 choice to make DOT the unconditional default and to avoid TTY-sensitive graph presentation. It does not change the graph model or JSON envelope.
Context
Section titled “Context”adr graph originally emitted Graphviz DOT by default and JSON on request. DOT
is a useful interchange format, but its source is not a useful interactive
answer. The dogfood corpus now contains 33 decisions and 144 relationships; raw
DOT resembles a pasted corpus, while a terminal network drawing of the same
graph becomes a crossing-heavy hairball.
The machine paths are already useful and consumed. Agents can request JSON,
renderers can consume DOT, and scripts may rely on bare adr graph through a
pipe. Improving the human experience must not turn those invocations into
terminal prose or ANSI output.
Mermaid is also a useful text renderer: GitHub and documentation systems can lay it out visually without adrkit carrying a browser, Graphviz executable, or layout dependency. Native SVG or HTML would require one of those costs.
Decision
Section titled “Decision”We will select graph presentation at the CLI boundary:
- The requested format defaults to
auto. autoresolves toterminalonly when stdout is a TTY. It resolves todotfor pipes, redirects, captured subprocesses, and CI.- Explicit
terminal,dot,json, andmermaidformats always win. - TTY detection, terminal width, and ANSI styling remain in
@adrkit/cli. Graph construction, filtering, DOT, JSON, and Mermaid rendering remain pure in@adrkit/core. --focus <id>keeps the named node, matching incident edges, and their endpoints. Repeatable--kindvalues are ORed acrosssupersedes,relatesTo, andconflictsWith. Every concrete format renders the same filtered graph.- Sparse terminal views list decisions and relationships. Focused views split incoming from outgoing relationships. Dense views report status and edge counts plus the most connected decisions, then direct the user to a focused filter rather than drawing a misleading network. Node and per-direction relationship budgets keep large sparse and focused views bounded.
- DOT gains visible statuses and deterministic styles from the portable adrkit palette. Mermaid labels also include status text; neither renderer relies on color alone.
- The graph JSON shape remains exactly
{ nodes, edges }, with existing node and edge fields, historical locale ordering, and missing-target omission unchanged. - Terminal title truncation uses grapheme boundaries and terminal display cells so multilingual titles do not overflow or split.
- Invalid corpus records do not suppress the valid projection: graph emits
the selected format from valid records, writes error findings to stderr, and
exits
1. A focused invalid record is diagnosed as invalid rather than absent. - We will not spawn Graphviz or ship native SVG/HTML in this surface. DOT piped
to
dot -Tsvgis the explicit SVG path; a dependency-bearing renderer remains downstream scope under ADR-0030.
Options considered
Section titled “Options considered”Option A: TTY-aware presentation with explicit deterministic formats
Section titled “Option A: TTY-aware presentation with explicit deterministic formats”Chosen. It improves the direct command while preserving bare piped output and all explicit machine channels. Focus filters solve the dense-corpus problem without inventing a layout engine.
Option B: Add formats but keep DOT as the interactive default
Section titled “Option B: Add formats but keep DOT as the interactive default”This is maximally conservative, but most humans never discover the better view. It leaves the primary command experience in the state that forced this decision.
Option C: Make terminal prose the unconditional default
Section titled “Option C: Make terminal prose the unconditional default”This breaks scripts and agents that capture bare adr graph. Requiring every
consumer to add --format dot is unnecessary when stdout already provides a
reliable compatibility boundary.
Option D: Render native SVG/HTML inside the CLI
Section titled “Option D: Render native SVG/HTML inside the CLI”This produces a file that opens directly, but it requires a system Graphviz dependency, a substantial layout/WASM package, or an in-house layout engine. Those costs are disproportionate while deterministic DOT and Mermaid already feed mature renderers.
Trade-offs
Section titled “Trade-offs”- Bare
adr graphis now environment-sensitive by design. The same invocation differs between a terminal and a pipe, so documentation must state the boundary precisely. - Polished DOT intentionally changes DOT bytes. Its node ids, relationship
directions, edge labels, and
statusattributes remain stable; consumers requiring byte-level output must pin their expected adrkit version. - The terminal overview is an instrument, not a complete visualization of every dense edge. Completeness remains available through DOT, JSON, Mermaid, and filtered terminal views.
- Graph now gives corpus errors exit-code authority after emitting the valid
projection; callers that previously ignored invalid records will observe
exit
1and diagnostics on stderr. - Mermaid source is deterministic, but final layout depends on the downstream Mermaid renderer version.
Consequences
Section titled “Consequences”- Easier: a human can run
adr graph, identify corpus shape and hubs, and focus a useful neighborhood without leaving the terminal. - Easier: GitHub and docs users have a dependency-free Mermaid channel.
- Easier: Graphviz output carries useful status and relationship styling before external rendering.
- Harder: help, completions, tests, and docs must cover five requested format values and the TTY negotiation rule.
- How we would know this was wrong: users report that redirected bare output is no longer DOT, JSON changes shape, terminal views hide the route to full output, or focused views still recover most of the dense corpus.
- Revisit if a stable, dependency-appropriate layout engine can produce self-contained accessible SVG without compromising deterministic Node 22 packaging.
Action items
Section titled “Action items”- Add pure graph filtering and Mermaid rendering to
@adrkit/core. - Add the TTY-aware terminal renderer and
autoselection to the CLI. - Add
--focusand repeatable--kindto help and shell completions. - Preserve piped DOT and the graph JSON envelope with contract tests.
- Document terminal, Mermaid, Graphviz SVG, and JSON workflows.
- Add installed-tarball Node canaries for every graph channel.
- Gather external evidence for the interactive view under ADR-0014.