Why it exists
Most code-graph tools stop at symbols and references. That tells you where a name appears. It cannot tell you how a value moves, and that gap is where the interesting questions live. Does this request parameter reach that SQL call? Which of two near-identical functions checks its input before the lookup, and which one does not? What can flow into this buffer?
Lachesis is built around the answer. Its dataflow edges, value-flow, points-to, taint and aliasing, alongside resolved and possible call edges, let a tool reason about reachability and tainted flow instead of pattern-matching text and hoping. And because it parses with the language's own compiler, it answers from the parse, not the spelling.
What you can do with it
A graph you query, not a report you read.
Real compilers, not regexes
Parses with the language's own compiler, so it never loses a caller to a rename, an alias, or an import indirection. It answers from the parse, not the spelling.
A full dataflow layer
Value-flow, points-to, taint and aliasing edges, so you can ask about reachability and tainted flow, not just where a symbol appears.
One graph, four languages
C, Python, TypeScript and JavaScript in a single graph, stored in an embedded columnar database that opens in well under a second.
Built for agents
A small navigation API and an MCP server hand the graph to a person or an LLM, so an agent can reason over real source with compiler fidelity.
Confidence on every edge
Each edge states how sure it is and where it came from, so you can tell an exact fact from a safe over-approximation.
Security-shaped questions
Guard coverage, sibling comparison, and source-to-sink reachability are first-class, the questions a reviewer actually asks.
Quickstart
Use the complete installer for the model-backed local stack, or install the headless package when you only need CLI/MCP access. Both paths run locally and need no account.
git clone https://github.com/UnboundCompute/lachesis-ui cd lachesis-ui ./scripts/install.sh export PATH="$HOME/.lachesis/bin:$PATH" ~/.lachesis/build-graph.sh ./my-project # build with the reviewed engine + catalog lachesis-ui # explore the graph
For a headless install, use pip install lachesis-cpg and point ATROPOS_ROOT at a reviewed Atropos checkout or installed model pack. The TUI installer is the shortest complete path.
See it work
Two sibling functions reach the same database call. One checks the caller's tenant first; the other does not. A symbol index sees both call findById and stops there. Lachesis tells them apart by following the value.
~/.lachesis/venv/bin/lachesis-analyze lachesis/frontends/typescript/fixtures/project example.kuzu ~/.lachesis/venv/bin/lachesis-query --format text example.kuzu overview
# overview Project: layered-project Languages: javascript, typescript Canonical graph: 3307 nodes / 6078 edges Security paths: 6 Guard differentials: 1
One guard differential: a pair of siblings reaching the same sink where one authorizes and one does not. Ask about the unguarded one:
lachesis-query --format text example.kuzu handler-security getDocument
"status": "UNGUARDED", "guard_signal": null, "differential_siblings": [ "getInvoice" ]
getDocument reaches findById with no check, and the record names its guarded twin, getInvoice, directly. That is the finding: a fact that lives in how the value moves, not where the name appears.
Run it in your CI
The same analysis on every pull request. lachesis-action builds the graph on your own runner, with no external service or API key, and writes findings straight into GitHub code scanning as inline annotations.
# .github/workflows/lachesis.yml name: Lachesis on: [pull_request] permissions: security-events: write # upload findings to code scanning jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: UnboundCompute/lachesis-action@v1.0.5 id: lachesis with: source: "." post-comments: "false" lachesis-ref: "v0.1.7" atropos-ref: "v1.7.1" - uses: github/codeql-action/upload-sarif@v3 if: ${{ always() && steps.lachesis.outputs.sarif-file != '' }} with: sarif_file: ${{ steps.lachesis.outputs.sarif-file }}
Findings come back at three levels, the same distinctions the graph draws: errors for guard differentials, where one function authorizes a caller and a sibling reaching the same sink does not; warnings for unguarded sinks; and notes for guarded paths. It emits SARIF, so results land in the Security tab and as annotations on the diff. MIT licensed.
See it on a real pull request: five inline findings on a Flask control plane → — three guard-differential errors and two guarded notes, posted straight onto the diff.
Lachesis is the open code-property-graph engine that powers UnboundCompute, our hosted autonomous security researcher. Use it standalone, or let us run it at scale, tuned and adjudicated.
See the researcher →