> For the complete documentation index, see [llms.txt](https://docs.controltheory.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.controltheory.com/controltheory-documentation/dstl8-docs/code-graph.md).

# Code Graph

Connect deploys and code to incidents — without giving anyone your source code

The Code Graph connects **what changed** to **what broke**. A one-line addition to your CI pipeline builds a map of your repo *inside your own build environment* and pushes only that map to Dstl8. Möbius then answers questions like:

> Errors began at 14:02. The `checkout` deploy at 13:58 changed `payments/client.go` — and the erroring log pattern is emitted from that exact file, line 212, in `chargeCard()`.

That works from **logs alone** — no APM agent, no tracing, no stack traces required. It's the join fabric between your deploys, your third-party dependencies, and your incidents - the graph ties it all together.

## How it works

Dstl8 already distills your logs into patterns, each with a stable fingerprint. The Code Graph extractor computes the same fingerprints from the *source side*: it parses your repo locally, finds every log statement, and derives the same pattern IDs from the format strings. Dstl8 links the two — so every runtime error pattern resolves to the `repo/file:line` and function that emits it, and every deploy resolves to the files and log statements it shipped.

```
  your environment                          │  your Dstl8 org
                                            │
  git repo ──▶ dstl8 graph push             │   snapshot store
               (parses locally, in CI)      │      │
                      │                     │      ├─▶ log patterns ⇄ log sites
                      ▼                     │      │       (pattern links)
          metadata artifact (JSON) ─────────┼──▶   ▼
          paths · service names · log       │   Möbius investigations · portal
          format strings — never source     │   Code page · MCP tools · CLI
```

Everything on the left runs in your environment. The only thing that crosses the line is the metadata artifact - which you can read in full before anything is sent.

## What leaves your repo (and what never does)

The pushed artifact contains, exhaustively:

1. Repo identity: remote URL, default branch, commit SHA, branch name.
2. Service manifest: declared/inferred service names this repo builds.
3. File inventory: relative paths, language, line counts, content hashes. **No file contents.**
4. Log-call sites: file, line, enclosing function *name*, logger callee name, severity hint, and the **format string of the log statement** (plus its normalized token form and ID).
5. Symbol names + kinds + locations; import/call edges between symbols/files; external dependency identifiers (package names from manifests, e.g. `stripe-go`).
6. Diff summary vs previously pushed commit: changed file paths, added/removed/modified symbols and log sites.

**What it never contains:** function bodies, comments, string literals other than log/error format strings, secrets/config values, embedded data files, git history/authors (author names deliberately excluded).

The only "code" content in the artifact is log format strings. The graph adds *where they live*, not *what they say*. Everything else is names and paths. Unlike other tools, Dstl8 never fetches source server-side: there is no repo cloning, no SCM tokens, etc.

`.gitignore` is always respected, and a [`.dstl8ignore`](/controltheory-documentation/dstl8-docs/code-graph/configuration.md) plus `--exclude` flags let you carve out anything else. Only git-tracked files are ever scanned.

## Audit it yourself

Nothing is sent until you run `push`, and the artifact is plain JSON you can read first:

```bash
dstl8 graph build --dry-run              # summary on stderr, full artifact JSON on stdout
dstl8 graph build --dry-run | jq '.log_sites[:3]'
dstl8 graph build -o graph.json          # write it to a file for review
```

The `--dry-run` summary looks like this:

```
Repo:        github.com/acme/checkout
Branch:      main (default: main)
Commit:      9f2c1ab4e5d6… (2026-08-12 14:31:02)
Files:       391 (12 skipped)
Log sites:   1240
Symbols:     2210
Edges:       5804
Services:    checkout (dstl8_yaml), checkout-worker (dstl8_yaml)
Diff:        vs 11aa22bb33cc — 3 files changed, 2 sites added, 1 removed
Graph hash:  sha256…
```

and each log site in the artifact is exactly this shape - the format string, where it lives, and its pattern fingerprint:

```json
{
  "id": "ls-3f9a2c81d4",
  "path": "payments/client.go",
  "line": 212,
  "function": "chargeCard",
  "callee": "log.Errorf",
  "severity_hint": "error",
  "template": "connection refused to <*> after <*> retries",
  "tokens": ["connection", "refused", "to", "<*>", "after", "<*>", "retries"],
  "template_id": "pt-ab12cd34ef",
  "confidence": "extracted"
}
```

A `push` uploads those same bytes: `dstl8 graph build -o graph.json` followed by `dstl8 graph push --file graph.json` sends exactly the file you reviewed.

## Quick start

### GitHub Actions

```yaml
# .github/workflows/codegraph.yml
name: dstl8 code graph
on:
  push:
    branches: [main]        # default branch only — the server rejects others
  schedule:
    - cron: "17 6 * * 1"    # weekly refresh keeps low-traffic repos current
jobs:
  codegraph:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 50    # enough history to diff against the last push
      - uses: control-theory/dstl8/.github/actions/dstl8-codegraph@main
        with:
          api-url: ${{ vars.DSTL8_EVENT_API_URL }}
          token: ${{ secrets.DSTL8_EVENT_TOKEN }}
```

The action is fail-open: it never breaks your build. It uses the same `dstl8_` token as the [events action](/controltheory-documentation/dstl8-docs/events.md). Full inputs and non-GitHub recipes: [CI integration](/controltheory-documentation/dstl8-docs/code-graph/ci.md).

### Any CI, or locally

```bash
dstl8 graph build --dry-run          # see exactly what would be sent
dstl8 graph push                     # build + upload (auth via dstl8 login,
                                     #   or DSTL8_API_TOKEN + DSTL8_API_URL in CI)
dstl8 graph repos                    # what's registered for your org
```

## What you get

* **Pattern → source:** every distilled log pattern gets linked to the code that emits it. Incident evidence resolves to `repo/file:line`, with the function name and last-shipped commit.
* **Deploy → change set:** a deploy event with a commit SHA expands into the files and log statements that deploy shipped.
* **Cause with receipts:** when a deploy changed a file that emits the erroring pattern, Möbius cites the event, the file, and the line together.
* **Blast radius:** symbol search, dependency traversal, and per-repo third-party SDK inventories - so a Stripe outage correlates to exactly the services that import the Stripe SDK.

{% hint style="info" %}
**When do links appear?** Dstl8 joins runtime patterns to source locations on a background sweep, so links typically show up within minutes of a push. Your first push for a repo also triggers a one-time backfill over the last 30 days (clamped to your log retention), so incidents that happened *before* you pushed the graph get their code locations too - you do not have to wait for a pattern to fire again. Re-pushing after a commit re-runs the backfill against the new snapshot.
{% endhint %}

The same six MCP tools Möbius uses (`list_code_repos`, `code_for_pattern`, `code_changes`, `find_symbol`, `code_impact`, `service_dependencies`) are available in Claude Code, Cursor, and anything else connected through [MCP integration](/controltheory-documentation/dstl8-docs/mcp-integration.md) - see [MCP tools](/controltheory-documentation/dstl8-docs/code-graph/mcp-tools.md).

## Going deeper

* [CLI reference](/controltheory-documentation/dstl8-docs/code-graph/cli.md) — every `dstl8 graph` flag, exit-code behavior, and copy-paste examples.
* [Configuration](/controltheory-documentation/dstl8-docs/code-graph/configuration.md) — `.dstl8.yaml` services, `.dstl8ignore`, built-in excludes, and language coverage.
* [CI integration](/controltheory-documentation/dstl8-docs/code-graph/ci.md) — the GitHub Action, GitLab and Jenkins recipes, and token setup.
* [MCP tools](/controltheory-documentation/dstl8-docs/code-graph/mcp-tools.md) — the six code tools and the deploy-correlation workflow.

{% hint style="info" %}
**Beta.** Graph pushes track the repo's default branch only - pushes from other branches are skipped harmlessly. Pushed graphs appear in the portal on the **Code** page. Snapshot retention follows your log-data retention; an unchanged-but-active repo stays fresh automatically, and the recommended [weekly cron trigger](/controltheory-documentation/dstl8-docs/code-graph/ci.md) keeps low-traffic repos inside the window.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.controltheory.com/controltheory-documentation/dstl8-docs/code-graph.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
