trusty-analyze 0.7.2

Sidecar code-analysis daemon for trusty-search: complexity, smells, quality, facts
Documentation

trusty-analyze

crates.io License: MIT

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-search daemon.

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. Start trusty-search before starting trusty-analyze.

Install trusty-search: cargo install --git https://github.com/bobmatnyc/trusty-tools trusty-search --locked or 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
curl -fsSL \
  "https://github.com/bobmatnyc/trusty-tools/releases/download/trusty-analyze-v${VERSION}/trusty-analyze-aarch64-apple-darwin.tar.gz" \
  | tar xz
sudo mv trusty-analyze /usr/local/bin/

# Linux x86_64 — example for v0.5.0
VERSION=0.5.0
curl -fsSL \
  "https://github.com/bobmatnyc/trusty-tools/releases/download/trusty-analyze-v${VERSION}/trusty-analyze-x86_64-unknown-linux-gnu.tar.gz" \
  | tar xz
sudo mv trusty-analyze /usr/local/bin/

Check the Releases page for the exact artifact names for your version.

Install with cargo

Standard install — macOS arm64 or Linux glibc ≥ 2.38:

cargo install --git https://github.com/bobmatnyc/trusty-tools trusty-analyze --locked

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
curl -fsSL \
  "https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-linux-x64-${ORT_VERSION}.tgz" \
  | sudo tar xz -C /opt
sudo ln -sf "/opt/onnxruntime-linux-x64-${ORT_VERSION}" /opt/onnxruntime

Step 2 — build without the bundled ORT:

cargo install --git https://github.com/bobmatnyc/trusty-tools trusty-analyze \
    --locked --no-default-features --features http-server,load-dynamic

Step 3 — export ORT_DYLIB_PATH and start the daemon:

export ORT_DYLIB_PATH=/opt/onnxruntime/lib/libonnxruntime.so
trusty-analyze serve --search-url http://127.0.0.1:7878

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):

cargo install --git https://github.com/bobmatnyc/trusty-tools trusty-analyze \
    --locked --no-default-features --features http-server

The installed binary is named trusty-analyze.

With Homebrew (recommended)

brew tap bobmatnyc/trusty
brew install trusty-analyze

Or install directly without tapping:

brew install bobmatnyc/trusty/trusty-analyze

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)
trusty-search daemon

# Run the analyzer sidecar
trusty-analyze serve --search-url http://127.0.0.1:7878

# Analyze a named index
trusty-analyze analyze <index-id> --top-k 20

# Check liveness
trusty-analyze health

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:
curl http://127.0.0.1:$(trusty-analyze port)/health
# → {"status":"ok","search_reachable":true}

# Or with the full host:port form:
curl http://$(trusty-analyze port --addr)/health

# Hard-coded form (works when port is always 7879):
curl http://127.0.0.1:7879/health

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:

trusty-analyze port          # bare port:     7879
trusty-analyze port --addr   # host:port:     127.0.0.1:7879
trusty-analyze port --json   # JSON:          {"addr":"127.0.0.1","port":7879}

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:

{
  "mcpServers": {
    "trusty-analyzer": {
      "command": "trusty-analyze",
      "args": ["serve", "--mcp"],
      "env": {}
    }
  }
}

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)

export OPENROUTER_API_KEY=sk-or-v1-...
export TRUSTY_LLM_MODEL=openai/gpt-4o-mini   # default; override as needed
trusty-analyze serve --search-url http://127.0.0.1:7878

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.
export TRUSTY_LLM_MODEL=bedrock/us.anthropic.claude-sonnet-4-6

# AWS credentials (any supported form):
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1           # or: export TRUSTY_AWS_REGION=eu-west-1

trusty-analyze serve --search-url http://127.0.0.1:7878

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
cargo build -p trusty-analyze

# Test
cargo test -p trusty-analyze

# Lint
cargo clippy -p trusty-analyze --all-targets -- -D warnings

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 cargo publish -p trusty-analyze

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.

Repository

https://github.com/bobmatnyc/trusty-tools