Metadata-Version: 2.4
Name: reachgraph
Version: 0.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Rust
Classifier: Topic :: Software Development :: Quality Assurance
License-File: LICENSE-MIT
License-File: LICENSE-APACHE
License-File: THIRD-PARTY-LICENSES.md
Summary: An endpoint-rooted call graph for a repository, as a static artifact.
Keywords: call-graph,static-analysis,rust,reachability
License-Expression: MIT OR Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Repository, https://github.com/m-agahi/reachgraph

# reachgraph

An endpoint-rooted call graph for a repository, emitted as a static artifact.

reachgraph starts from the endpoints a service actually exposes — a gRPC method, an HTTP
route — and walks the call graph outwards from each one. What it produces is not "every
function and who calls it" but an answer to a narrower and more useful question: **which
code is reachable from which endpoint version, and which code is reachable from none of
them.**

It is one binary. It installs from PyPI, links its analysis engine in-process, downloads
nothing at run time, and runs no subprocess of its own beyond the target language's own
build toolchain (ADR-0001).

## Install

```console
$ pip install reachgraph
$ reachgraph --version
```

The wheel contains an executable and no Python. Nothing is importable; nothing is
compiled at install time.

## Use

```console
$ reachgraph ./some-repo -o ./out
$ reachgraph serve ./out
```

`./out` is a static directory: `index.html`, one shard per root under `graph/`, a
single-file `overview.html`, and the machine-readable `endpoints.json`,
`unreachable.json` and `run.json` beside them. `serve` exists only because `file://`
blocks `fetch()` for the sharded pages — `overview.html` opens straight from disk
(ADR-0006).

**The artifact is a structural map of your repository.** It carries file paths, function
and method names, doc comment text and service topology. Treat it with the same care as
the source, and read the warning the binary prints before publishing one anywhere.

## Runtime

reachgraph analyses a whole repository in one pass. It is a CI-generated artefact, not an
interactive tool: run it in a workflow and read the output, rather than expecting it to
answer a question while you wait.

**MEASURED 2026-09-19**, the shipped release profile, warm page cache, against one small
Rust workspace — 8 units, 227 symbols, 364 edges: **4.86 s wall and 900 MB peak resident**.
Three runs of `command time -v ./target/release/reachgraph …` gave 4.86 / 4.63 / 4.91 s
and 900 224 / 898 248 / 901 044 kB; the medians are the numbers above. The binary's own
`run.json` accounts for 4.53 / 4.30 / 4.60 s of those, nearly all of it analysis.

That figure is one repository and it is small. **It does not establish what reachgraph
costs on a large one.** `docs/design.md` §8's "minutes, not seconds" was measured against
the LSP round-trip architecture ADR-0001 rejected, and it has never been re-measured
against the linked engine at scale. Peak resident memory is the number to watch: 900 MB
on 227 symbols is rust-analyzer's own working set, and it grows with the repository
rather than with the graph.

## What it does not claim

An absent edge is not a proven absence. reachgraph reports the limits of each run — in
the terminal, and inside the artifact — and the wording is deliberate throughout: code is
described as **not reachable from any endpoint version in this index**, never as dead
(ADR-0007). Proc-macro expansion is off in v0.1 (ADR-0728) and generated code is not
loaded, so calls crossing either are unmeasured rather than absent.

## Licence

**MIT OR Apache-2.0**, at your option. See [LICENSE-MIT](LICENSE-MIT) and
[LICENSE-APACHE](LICENSE-APACHE).

The binary statically links its dependencies and the emitted artifact carries vendored
JavaScript, so both redistribute third-party code:
[THIRD-PARTY-LICENSES.md](THIRD-PARTY-LICENSES.md) covers the crates and the bundles, and
every emitted artifact carries its own `vendor/LICENSES.txt`.

The four-layer architecture is derived from [crabviz](https://github.com/chanhx/crabviz),
which is AGPL-3.0. Ideas are not copyrightable and the credit belongs in prose; **not one
line of its code is here**, and CI asserts that.

## Contributing

`docs/adr/` holds the decisions and `docs/plans/` the per-module implementation plans.
Every factual claim in either is labelled **MEASURED** or **INFERRED**; keep that up.

```console
$ cargo test --workspace --all-features
$ pre-commit run --all-files
```

