trusty-analyze
Sidecar code-analysis daemon for trusty-search. Fetches chunk corpora from the trusty-search daemon, runs static analysis, and serves results via HTTP (port 7879) and MCP stdio.
📚 Documentation
Full documentation lives at the workspace top level in
docs/trusty-analyze/: the
research,
sessions, and
regression-testing subdirs.
This README and the rustdoc stay in-crate; everything else lives under docs/.
Prerequisites
trusty-analyze requires a running
trusty-searchdaemon.The analyzer performs a startup health check against
http://127.0.0.1:7878/health(or the URL given by--search-url) and exits with code 1 if that check fails. There is no standalone or offline mode. Starttrusty-searchbefore startingtrusty-analyze.Install trusty-search:
cargo install --git https://github.com/bobmatnyc/trusty-tools trusty-search --lockedor see trusty-search's README for prebuilt binaries.
Installation
Install from prebuilt binary
Prebuilt binaries for macOS arm64 and Linux x86_64 are published on the
GitHub Releases page under
tags of the form trusty-analyze-v<version> (e.g. trusty-analyze-v0.5.0).
# macOS arm64 (Apple Silicon) — example for v0.5.0
VERSION=0.5.0
|
# Linux x86_64 — example for v0.5.0
VERSION=0.5.0
|
Check the Releases page for the exact artifact names for your version.
Install with cargo
Standard install — macOS arm64 or Linux glibc ≥ 2.38:
The default build bundles a prebuilt ONNX Runtime (via fastembed/ort-download-binaries)
for the neural concept-clustering embedder. This is the correct choice for macOS and
any Linux host with glibc 2.38 or later.
Amazon Linux 2023 / glibc < 2.38 (system ORT):
The bundled ONNX Runtime static library (included by the default bundled-ort feature)
is built against glibc 2.38. Linking it on AL2023 (glibc 2.34) or any other host with
an older glibc fails at link time with an unresolved __isoc23_strtol symbol (glibc
2.38-only). The load-dynamic feature bypasses the static bundle entirely: ort loads
libonnxruntime.so via libloading at runtime instead of linking it at build time.
Step 1 — install a glibc-compatible ONNX Runtime. The official Microsoft CPU release is built against glibc 2.17 and runs on AL2023 without issues:
# ORT 1.24.2 CPU (matches the version used by ort-sys 2.0.0-rc.12 / fastembed 5.x)
ORT_VERSION=1.24.2
|
Step 2 — build without the bundled ORT:
Step 3 — export ORT_DYLIB_PATH and start the daemon:
Add ORT_DYLIB_PATH to your shell profile or systemd/launchd service unit so it
persists across restarts. The exact ORT version (1.24.2) must match what
ort-sys/fastembed expects; see the ort-sys version in Cargo.lock to
confirm the version before upgrading ORT.
If no system ORT is available, install without any ORT backend. The daemon will still run with the deterministic BoW embedder (no semantic clustering):
The installed binary is named trusty-analyze.
With Homebrew (recommended)
Or install directly without tapping:
Homebrew provides:
- Automatic updates via
brew upgrade trusty-analyze - Standard macOS / Linux PATH integration
- Easy dependency management
Quick Start
# trusty-search must be running first (hard runtime dependency)
# Run the analyzer sidecar
# Analyze a named index
# Check liveness
Ops health check
Probe the daemon over HTTP without the CLI — useful for monitoring, systemd
ExecStartPost, or container readiness probes:
# Port-safe idiom — resolves the live port without hard-coding 7879:
# → {"status":"ok","search_reachable":true}
# Or with the full host:port form:
# Hard-coded form (works when port is always 7879):
search_reachable reflects whether the upstream trusty-search daemon (port
7878) is responding; a false here means analysis endpoints will fail even
though the analyzer process itself is up.
Port discovery (trusty-analyze port)
The port subcommand reads the daemon's live address from its discovery file
so scripts work even when the daemon auto-selected a free port:
Falls back to 7879 when no daemon is running.
Features
- Cyclomatic and cognitive complexity per chunk, file, and index
- Code smell detection with configurable thresholds and named categories
- Quality grade aggregation (A–F) per file and per index
- Git blame temporal decay scoring (stale high-complexity code surfaces first)
- Concept clustering (k-means over embeddings, BoW or neural)
- Facts store:
(subject, predicate, object)knowledge triples, persisted in redb - SCIP protobuf ingest for LSP-quality symbol data
- Full HTTP API + MCP stdio server (every endpoint has a tool equivalent)
Claude Code Integration
Add to your project's .mcp.json:
trusty-search must already be running. The analyzer performs a startup health
check against http://127.0.0.1:7878/health and exits with code 1 if
unreachable.
MCP Tools
The MCP server registers 17 tools (authoritative source: src/mcp/mod.rs
tool_definitions):
| Tool | HTTP equivalent |
|---|---|
analyzer_health |
GET /health |
complexity_hotspots |
GET /indexes/:id/complexity_hotspots |
find_smells |
GET /indexes/:id/smells |
analyze_quality |
GET /indexes/:id/quality |
run_diagnostics |
(composite diagnostics run) |
list_facts |
GET /facts |
upsert_fact |
POST /facts |
delete_fact |
DELETE /facts/:id |
ingest_scip |
POST /indexes/:id/scip |
cluster_concepts |
GET /indexes/:id/clusters |
extract_graph |
knowledge-graph extraction |
extract_ner |
named-entity extraction (optional ONNX) |
list_entities |
enumerate extracted entities |
suggest_refactors |
refactor suggestions |
review_diff |
review a unified diff |
review_github_pr |
review a GitHub pull request |
deep_analysis |
combined deep-analysis pass |
HTTP API
Port 7879. Requires trusty-search on port 7878.
GET /health
GET /indexes/:id/complexity_hotspots[?top_k=N]
GET /indexes/:id/smells[?category=<name>]
GET /indexes/:id/quality
GET /indexes/:id/clusters?k=N&method=bow|neural
GET /facts[?subject=<s>&predicate=<p>]
POST /facts
DELETE /facts/:id
POST /indexes/:id/scip
Deep-Analysis LLM Pass
POST /analyze/deep (and the deep_analysis MCP tool) generate a prose
narrative for an analyzed index using an LLM. The provider is selected by
the TRUSTY_LLM_MODEL environment variable.
Using OpenRouter (default)
# default; override as needed
Using AWS Bedrock
Set the model id with the bedrock/ prefix. No OpenRouter key is required —
auth uses the standard AWS credential chain (env vars, ~/.aws/credentials,
IAM role, SSO).
# Claude Sonnet 4.6 via cross-region inference profile (recommended):
# Note: Sonnet 4.6 drops the date stamp and -v1:0 suffix from the profile id.
# AWS credentials (any supported form):
# or: export TRUSTY_AWS_REGION=eu-west-1
When the model id starts with bedrock/, the daemon routes the LLM call
through aws-sdk-bedrockruntime's Converse endpoint rather than OpenRouter.
The rest of the deep-analysis pipeline (prompt construction, narrative
accumulation, recommendations extraction) is identical.
Bedrock environment variables
| Variable | Default | Description |
|---|---|---|
TRUSTY_LLM_MODEL |
openai/gpt-4o-mini |
Model id. Prefix with bedrock/ to select AWS Bedrock. |
TRUSTY_AWS_REGION |
— | AWS region for Bedrock calls (takes priority over AWS_REGION). |
AWS_REGION |
us-east-1 |
Fallback AWS region (standard env var). |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY |
— | Static AWS credentials. Alternatives: AWS_PROFILE, IAM role, SSO. |
Configuration
| Variable | Default | Description |
|---|---|---|
TRUSTY_SEARCH_URL |
http://127.0.0.1:7878 |
trusty-search daemon address |
TRUSTY_ANALYZER_PORT |
7879 |
Analyzer listen port |
RUST_LOG |
warn |
Tracing filter |
Feature Flags
| Flag | Description |
|---|---|
http-server |
Axum HTTP daemon (enabled by default). Required for the trusty-analyze binary. |
bundled-ort |
Default. Bundle the static ONNX Runtime libs via fastembed. Requires glibc ≥ 2.38. |
load-dynamic |
Load ONNX Runtime dynamically from ORT_DYLIB_PATH. Use on glibc < 2.38 (AL2023). Mutually exclusive with bundled-ort. |
cuda |
GPU-accelerated embedding via ONNX Runtime CUDA EP. Always pair with --no-default-features. |
ner |
Optional ONNX-backed named entity recognition (separate model file required). |
ORT backend selection summary
| Host | Recommended install command |
|---|---|
| macOS, Linux glibc ≥ 2.38 | cargo install trusty-analyze (default, bundled ORT) |
| Amazon Linux 2023 / glibc 2.34 | cargo install trusty-analyze --no-default-features --features http-server,load-dynamic + ORT_DYLIB_PATH |
| No ONNX Runtime available | cargo install trusty-analyze --no-default-features --features http-server (BoW fallback) |
| CUDA GPU | cargo install trusty-analyze --no-default-features --features http-server,cuda + ORT_DYLIB_PATH |
Architecture
The crate is a single trusty-analyze package containing the CLI binary
(trusty-analyze) and a library. All analysis engines, the HTTP server, and the
MCP stdio server live within this one crate. Shared types (complexity metrics,
code smells, knowledge-graph entities, facts) come from trusty-common.
trusty-search (port 7878) trusty-analyze (port 7879)
GET /indexes/:id/chunks ──────────► complexity analysis (tree-sitter)
(bulk corpus export) blame + temporal decay
quality grade aggregation
k-means concept clustering
facts store (redb)
axum HTTP API + MCP stdio
Development
# Build
# Test
# Lint
See CLAUDE.md for full architecture, API reference, and project history.
Publishing
trusty-analyze is a UI-embedding crate: its build.rs invokes pnpm to
build the embedded Svelte dashboard served from src/service/ unless told to
skip it. When publishing, always set SKIP_UI_BUILD=1 so the committed
ui-dist/ bundle is used as-is:
SKIP_UI_BUILD=1
Without the flag, cargo publish runs build.rs inside the verification
tarball, where pnpm tries to write outside OUT_DIR and the publish fails.
The same flag applies to the sibling UI-embedding crates (trusty-search,
trusty-memory). See the workspace release workflow in the root
CLAUDE.md and the cargo-publish skill for the full
tag → publish → install sequence (trusty-analyze-v<version>).
License
Licensed under the MIT License.