# ra — runtime analysis for Ruby > Analysis of what Ruby code actually did at runtime, for coding agents (MCP), editors (LSP) and the > command line. Recording is a Ruby gem; analysis is a single static binary. This file is the > machine-readable install and usage contract for an agent setting `ra` up. Steps marked (building) > are not live yet. ## Install (two pieces) 1. The analysis binary `ra`, any one of (building — live with the first release): - `curl -fsSL https://www.runtimeanalyz.ing/install.sh | sh` - `brew install runtimeanalyzing/tap/ra` - download `https://dl.runtimeanalyz.ing/free//ra-` and put it on PATH. `https://dl.runtimeanalyz.ing/free/stable.txt` names the current version. Platforms: `darwin-arm64`, `darwin-amd64`, `linux-arm64`, `linux-amd64`. `checksums.txt` beside the builds holds their SHA-256 sums. 2. The recorder gem (not added to any Gemfile): `gem install runtime_analysis` Sign in: `ra login` prints a URL and a code for the person to enter in a browser (free sign-up is there), waits, and saves the licence at ~/.config/runtime_analysis/licence. `ra login ` takes a licence key with no browser (CI: RA_LICENCE or RUNTIME_ANALYSIS_LICENCE in the environment). Usage events (tool names and outcomes, never code) are on unless RA_TELEMETRY=0. Every tool, `ra mcp` call and hover needs a sign-in; without one the answer is the line `Sign in to use ra: run ra login` (the editor is answered first and told once). CI: RA_LICENCE in the environment. Under a free answer the binary may print one line, on stderr, saying what a Pro tool would find in this recording; RA_UPGRADE_HINTS=0 or `ra upgrade --later` stops it, and `--json` never carries it. Verify: `ra doctor` (no questions, exit 1 if something is in the way: this binary, which ra PATH runs, signed in, the paid build, Ruby, the recorder gem, the recording, the agent's MCP config, the editor's LSP config). `ra doctor --json` gives the same as an array of {check, status, detail, fix} for an agent or a bug report. `ra setup` is the same walked through with an offer to fix each: PATH order, ra login, gem install, ra activate, ra record, `claude mcp add ra -- ra mcp` when Claude Code is on PATH (else the snippet below), the editor how, and the gem's own project edits (Gemfile, test hook) for a team that records in CI, default no. The installer runs it when there is a terminal; set RA_SETUP=0 to skip. The recorder and ra release together; the gem on RubyGems is currently behind, so doctor fails the gem check until a current gem is published. ## Record (always the Ruby gem, injected; no Gemfile change) - `ra record` — asks once what runs the tests, records them into `tmp/runtime_analysis` - `ra record dev` — records the dev server until Ctrl-C - `ra record -- ` — records any one command - `ra rerun ` — records again the examples that reached a file - `ra crystallise --rbs|--sorbet` — writes the types a recording saw as RBS or Sorbet sigs All three run the gem; the gem ships no executable of its own. ## Serve (a big recording) A terminal question reads the recording each time, which is 11 s on a 76 MB one. An answer slower than 2 s starts `ra serve --daemon` in the background: one process that holds the recording and answers the terminal in milliseconds, re-reads it when its files change, stops after an hour idle or when a newer ra asks, and never talks to the network. `ra serve --status`, `ra serve --stop`; `RA_SERVER=off` keeps every answer local. `ra mcp` and `ra lsp` hold the recording themselves. The recording is ignored via `.git/info/exclude`. Nothing leaves the machine. ## Analyse (free, local) - `ra what_calls '#'` - `ra what_it_receives '#'` - `ra who_actually_answered ''` - `ra where_nil_comes_from '#'` - `ra verify_mock ` - `ra tools` — list everything available - `ra mcp` — serve tools over MCP (stdio) for an agent. Config for any agent: `{ "mcpServers": { "ra": { "command": "ra", "args": ["mcp"] } } }`; Claude Code: `claude mcp add ra -- ra mcp` - `ra lsp` — language server for an editor (inlay hints, hover, go-to-type) ## Tiers - free: record then analyse raw files locally, limited toolset (the commands above) - pro: the free build lists every Pro tool by name (`ra tools`, MCP `tools/list`) and answers one with a line saying what it is; `ra upgrade` opens checkout, then `ra activate` with no code fetches the Pro build. Pro adds 29 tools, still local: call_stack, what_it_calls, how_it_got_here, how_to_reach, observed_shape, find_implementers, specs_that_reach, how_far_it_reached, whats_looping, where_time_goes, feature_envy, unit_test_candidates, coupling_map, break_cycle, stabilize_dep, split_package, relocate_file, refactor, what_a_change_touches, observe, split_interface, dead_api, scaffold, testing_pyramid, where_nil_blew_up, where_nil_would_break, check, prod_dead_api, whats_connected - team: `ra activate CODE` (team) adds `ra push` (ingest tokenised graph to the server), `ra team ` and `ra team sync` (serve across the team). Only this tier talks to the server. Stub it with `RA_INGEST_URL=http://localhost:PORT`. ## Editors `ra lsp` is a standard LSP server (inlay type hints, hover, go-to-type from real runs). - Neovim: point the built-in LSP client at it, e.g. `vim.lsp.start({ cmd = { "ra", "lsp" } })` for Ruby files. No plugin needed. - VS Code: a small extension launching `ra lsp` is building; any editor that runs a custom LSP command works today. ## Privacy Free and Pro: nothing leaves the machine. Team: only a tokenised graph (opaque tokens for class and method names, no source identity) is uploaded, and only when `ra push` is run. ## Docs - [Runtime Analysis](https://www.runtimeanalyz.ing/): the site, with the plans under `#plans` - [Install ra and ask your first question](https://www.runtimeanalyz.ing/install): one line installs the binary, which walks through sign-in, the recorder gem and a first recording, then MCP for an agent and LSP for an editor - [Configuring what gets recorded](https://www.runtimeanalyz.ing/configuration): which code is recorded by default, how to widen or narrow it, and why gems are left out unless asked for - [What leaves your machine](https://www.runtimeanalyz.ing/data): what is recorded and where it is kept; the recording never leaves the machine on any plan - [How the recorder works inside your process](https://www.runtimeanalyz.ing/native-sink): what the native recorder does on each traced call and what happens when it has a fault - [Questions and answers](https://www.runtimeanalyz.ing/questions): cost to run, what is recorded, how far to trust the answers, and what is built versus planned - [What it found in Redmine](https://www.runtimeanalyz.ing/redmine): the free gem on a clone of Redmine, in three commands - [Capabilities](https://www.runtimeanalyz.ing/capabilities): every tool by tier - [Roadmap](https://www.runtimeanalyz.ing/roadmap): what is built and what is next - [Contact](https://www.runtimeanalyz.ing/contact): a Pro trial, the hosted graph, or a question the site did not answer - [Legal](https://www.runtimeanalyz.ing/legal): who operates the site and sells the software - The READMEs (free, pro, team) ship with the binary and in the source tree under cli/. ## Tools Each free tool has a page at `https://www.runtimeanalyz.ing/tools/`: - [what_calls](https://www.runtimeanalyz.ing/tools/what_calls): every caller of a method in the recorded runs, with file, line and how often - [what_it_receives](https://www.runtimeanalyz.ing/tools/what_it_receives): for each argument of a method, the classes it was given and the messages the method sent it - [who_actually_answered](https://www.runtimeanalyz.ing/tools/who_actually_answered): at a duck-typed call site, the concrete classes that received the message - [where_nil_comes_from](https://www.runtimeanalyz.ing/tools/where_nil_comes_from): the methods that returned nil and the arguments that received nil - [verify_mock](https://www.runtimeanalyz.ing/tools/verify_mock): what each stub in a spec returns against what the real method returned in the recording The Pro tools listed under Tiers have pages at the same path.