# Code Graph Layer (Graphify) — Operator Guide

> Since v4.21.0. Opt-in, gated on `features.has_code_graph`. The **runtime**
> protocol (when to use the graph vs LSP vs Grep) lives in
> [`framework/agents/code-graph-protocol.md`](../agents/code-graph-protocol.md);
> this document covers the *plumbing* — install, config, lifecycle, fallback.

## 1. Why this exists

After removing the (unused, costly) RAG engine in v4.20.0, BALDART needed a
retrieval tier for **structural / relational** code questions — "what connects X
to Y", blast-radius of a change, which modules cluster — that Grep and even LSP
answer poorly. [Graphify](https://github.com/safishamsi/graphify) builds a code
knowledge graph (tree-sitter, 28 languages, **local/offline**) with native Leiden
community detection. The same graph also **re-activates the Karpathy LLM-wiki
auto-learning loop**: its native `GRAPH_REPORT.md` (god nodes, communities,
suggested questions) is the gap signal that feeds synthesis candidates.

## 2. What BALDART adds vs what Graphify already ships

Graphify is a complete tool on its own — it installs its **own** skill, an
always-on pre-tool hook, a post-commit git hook, and an MCP server. BALDART does
**not** reimplement any of that. It adds only:

- **Gating + config** (`features.has_code_graph` + `graph:` block).
- **Opt-in install** (`configure` interactive branch, `/graphify-bootstrap`, `doctor` backfill).
- **A retrieval protocol** telling BALDART's own agents *when* the graph is the right tier.
- **The wiki rebind** (wiki-curator / capture / `doc-graph-align` consume `GRAPH_REPORT.md`).
- **Fallback discipline** (silent degrade to LSP→Grep→Git).

Everything mutating is a thin wrapper over Graphify's native commands in
[`src/utils/graphify-installer.js`](../../src/utils/graphify-installer.js).
There is **no per-language adapter registry** (unlike LSP) — Graphify is one
language-agnostic tool.

## 3. The moving parts

| Part | Where | Role |
|------|-------|------|
| Config flag + block | `framework/templates/baldart.config.template.yml` | `features.has_code_graph` + `graph.{output_dir,auto_rebuild_hook,register_mcp}` |
| Installer wrapper | `src/utils/graphify-installer.js` | `detect/install/verify/buildGraph/installGitHook/installAlwaysOn/registerMcp/isStale` |
| Configure | `src/commands/configure.js` | autodetect (binary on PATH) + prompt + interactive install/build/wire |
| Update detector | `src/commands/update.js` | diffs the `graph:` block → offers `configure` (extended to diff nested top-level blocks) |
| Doctor | `src/commands/doctor.js` | `Code graph` line + `graph-install` / `graph-rebuild` / `graph-hook` actions |
| Retrieval protocol | `framework/agents/code-graph-protocol.md` | when to use the graph; budget; fallback |
| Wiki rebind | `llm-wiki-methodology.md`, `wiki-curator.md`, `wiki-review.routine.yml`, `capture` | GRAPH_REPORT.md → synthesis candidates |
| Nightly command | agent `doc-graph-aligner` + routine `doc-graph-align` + skill `/graph-align` | doc↔graph alignment |
| Bootstrap skill | `/graphify-bootstrap` | explicit install path (CI-safe backfill) |

## 4. Install lifecycle

```
features.has_code_graph: true
        │
        ├─ baldart configure (INTERACTIVE) ─→ pipx install graphifyy
        │      → graphify update .          (build, offline)
        │      → graphify <tool> install    (always-on per tools.enabled)
        │      → graphify hook install       (auto-rebuild, if auto_rebuild_hook)
        │      → claude mcp add … graphify-mcp (if register_mcp)
        │
        ├─ baldart configure --yes / CI ──→ writes the flag ONLY (no silent
        │      Python install) → doctor backfills
        │
        ├─ /graphify-bootstrap ───────────→ the explicit, full install path
        │
        └─ baldart doctor ────────────────→ graph-install (binary missing)
               graph-rebuild (stale: built_at_commit ≠ HEAD) · graph-hook (hook missing)
```

**CI behavior is deliberate**: a Python tool is never installed silently in
`--yes`/non-interactive runs. The flag is written from autodetect; `doctor` and
`/graphify-bootstrap` own the actual install.

## 5. Native commands BALDART relies on (all offline, 0 API cost)

| Purpose | Command |
|---------|---------|
| Build / refresh graph | `graphify update <root>` → `<root>/graphify-out/{graph.json, GRAPH_REPORT.md, graph.html}` |
| Auto-rebuild on commit | `graphify hook install` (post-commit + graph.json union merge-driver) |
| Always-on per tool | `graphify claude install` / `graphify codex install` / … |
| Query (relational) | `graphify query "…"`, `graphify path "A" "B"`, `graphify explain "X"`, `graphify affected "X"` |
| MCP server | `graphify-mcp [graph.json]` (stdio default; `--transport http` available) |
| Staleness (cron-safe) | `graphify check-update <root>`, or compare `graph.json.built_at_commit` to `git rev-parse HEAD` |

LLM API keys are needed **only** for `--wiki` / community naming (`graphify label`)
/ URL & vision ingestion — all optional. The structural graph + report are free.

## 6. Invariants

- **The graph is never canonical.** Synthesis candidates it produces cite repo
  SSOT and carry `canonicality: derived`.
- **Silent fallback.** No task aborts because the graph is missing — degrade to
  LSP→Grep→Git; surface setup gaps via `baldart doctor`, never mid-task.
- **`graphify-out/` is generated** — must be in `.gitignore`, never versioned.
- **No per-language registry.** Add nothing per language; Graphify handles 28 via
  tree-sitter. The wrapper composes native commands, never reimplements them.
- **Schema-change propagation** applies to `features.has_code_graph` + `graph.*`.

## 7. Adding capability later

The retrieval tier ships CLI-first; the MCP path is opt-in. To deepen the
integration (e.g. wire `graphify-mcp` as a first-class MCP tool, or use `--wiki`
community pages directly as wiki concept pages), extend `graphify-installer.js`
and the protocol module — do not fork Graphify's native behavior.
