ultra-trace

Deterministic Swift static analysis with an assist/gate split.

Python · Swift Core · optional Advanced SIL · Code on GitHub

The problem

Swift teams need static analysis that can gate a build offline and still help a human explore risky paths. Chat-only tools blur those jobs and send code to a model. I wanted those contracts separated.

Why I built it

I use explore to understand paths with LLM help. I use analyze to gate the build.

What I built

I built a deterministic static analysis CLI for Swift (Core), with optional Advanced SIL, bounded call summaries, and a Python frontend. Entry points are ultra-trace and python -m ultra_trace. macOS and Xcode are required to build the SwiftSyntax helper.

Dual mode:

  • explore — day-to-day assist. Optional LLM. Advisory. Soft exit unless you pass --fail-on-findings.
  • analyze — CI / nightly gate. Offline. LLM off. Same analysis engine.

Reports write markdown, JSON, and SARIF. High findings can carry proof artifacts with tiers. Privacy modes are offline, redacted, and full-assist. API keys live only in the appdir .env, never in YAML. Phases 1–6 are complete. Phase 7 covers platform maturity: Mac fleet bootstrap, perf budgets, SARIF export, and operator hygiene.

Three decisions

1. Dual mode is the product.

Assist and gate share one engine and keep different contracts. Explore is human-first and advisory. Analyze owns CI exit codes and severity thresholds. That split is the design, not a flag bolted on later.

2. The analyzer owns findings; the LLM is advisory only.

When assist is on, the model may propose an exploration plan, draft advisory wording, or emit optional llm.proposed_candidate items. It never changes severity, confidence, or proof tier. Offline wins over --llm-enabled. Proposed candidates never fail Core severity gates alone.

3. Proofs and privacy are engineered, not bolted on.

High findings get proof tiers: runnable scaffold, repro steps, path witness, or unsupported. Keys stay in the appdir .env. offline blocks network and forces the LLM off. Redacted and full-assist sanitize outbound text. Toolchain pins, drift checks, and SARIF support a Mac fleet and Code Scanning — not a demo script.

Proof

ultra-trace runtime architecture: Entry through config and modes into analyzer-owned engine, rule packs and proofs, then md/json/SARIF with advisory LLM assist
Runtime map — How ultra-trace boots and routes work: entry (ultra-trace / python -m ultra_trace) through config and modes (explore, analyze, repl, serve), discovery and Swift/Python frontends, into the analyzer-owned engine, rule packs and proofs, then md / json / SARIF. LLM assist stays advisory only — it never owns severity, confidence, or proof tier. Optional Advanced SIL falls back to Core when unavailable.

From the public repo:

  • Dual-mode recipes and named profiles (assist, ci, ci-full)
  • Fixtures and ci_analyze_samples.sh
  • SARIF export and GitHub Code Scanning example
  • Toolchain pins, bootstrap scripts, and operator guides
  • Exit codes and known limitations documented in the README

github.com/rdegraci/ultra-trace

Why I built it this way

I wanted a Swift analysis CLI that keeps assist and CI gate as separate contracts: a deterministic core, an optional LLM that cannot rewrite the gate, and proofs and privacy designed for a Mac fleet.