Skip to content
alex09xPublic

About

Remote code intelligence server for AI coding agents (MCP): rust-analyzer, gopls, clangd, pyright and TypeScript run on a LAN build node — semantic navigation, safe refactoring, edit validation, builds and tests without burning the laptop.

Topics

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Repository files navigation

⚡ prod-code

Remote code intelligence for fleets of coding agents

GitHub release License Rust Protocol

The analyzer, the builds and the tests run on a LAN node. The laptop edits.
Your checkout is mirrored to a gateway that keeps a warm analyzer for it (rust-analyzer in process; gopls, clangd, TypeScript, pyright, sourcekit-lsp as children) and runs commands there. Agents reach it as MCP tools, editors as a drop-in language server.

prod-code: Distributed Remote Code Intelligence Platform


Why

A language server was designed for one human typing in one checkout. What runs on a machine now is a fleet: a resident agent in the main checkout, workers in their own worktrees, each asking the analyzer the kind of question a human asks once a minute and asking it ten times a second. Every worktree brings its own analyzer and its own cargo test, and they share the cores with your editor.

prod-code moves all of it one hop away. Measured on this repository, with nothing compiled on the laptop:

hover on a warm workspace 1–4 ms
tool call over a persistent session ~10 ms
a one-shot CLI command from the laptop, end to end (prod-code hover …) ~0.1 s
cargo clippy --workspace --all-targets on a 32-core node, one file changed 1 s
cargo test --workspace — 565 tests 5 min
the same without the suite that starts real gateways 56 s
first load of a Rust workspace (build scripts, proc macros) ~45 s, once per worktree

These are recorded workloads; current test counts and timings are listed in each pull request. The live suite starts real gateways and drives their language servers. Unit and scripted-server tests complement those scenarios. The required coverage floor is 80% of regions per source file (python3 scripts/coverage.py --min 80); missing measurements fail the gate.

Architecture

Architecture: developer workstation to 9-node cluster, isolated worktree overlays over shared Salsa analysis

Click to view Mermaid flowchart and component mapping
flowchart TD
    subgraph ClientHost["Developer Workstation (Laptop / Desktop)"]
        Agent["AI Coding Agents\n(Claude Code, Codex, Antigravity)"]
        Editor["Code Editors\n(Zed, VS Code, Neovim)"]
        CLI["prod-code CLI"]

        Agent -->|"Native MCP (67 tools)"| MCPBridge["prod-code mcp"]
        Editor -->|"LSP protocol"| LSPBridge["prod-code lsp"]
        CLI -->|"Commands / Queries"| ClientCore["prod-code client"]

        MCPBridge & LSPBridge & ClientCore --> SyncEngine["Fast Mirror & Sync Engine\n(Base64 diffs, watermarks, local cache)"]
    end

    SyncEngine -->|"10 GbE LAN / Gossip (:9400)"| GatewayCluster

    subgraph GatewayCluster["Production Cluster (9 nodes · 355 CPU cores)"]
        subgraph LinuxAarch64["128-Core aarch64 (Ampere Altra)"]
            LinuxArmNode["Linux aarch64 build node (128 cpus)\nRust, Go, C++, Python, TS, Java, Kotlin"]
        end

        subgraph LinuxX86["High-Throughput x86_64 Nodes (192 cpus)"]
            LinuxX86Node1["Zen 5 build node (32 cpus)"]
            LinuxX86Node2["Zen 4 build node + telemetry (32 cpus)"]
            LinuxX86Node3["Polyglot build node (32 cpus)"]
            LinuxX86Storage["Storage & build nodes (96 cpus)"]
        end

        subgraph MacNodes["Apple Silicon macOS Nodes (35 cpus)"]
            MacNodeStudio["macOS build node (24 cpus) · Swift, Go"]
            MacNodeBook["macOS build node (11 cpus) · Swift"]
        end

        subgraph GatewayInternals["Gateway Architecture (per node)"]
            Router["Placement & Gossip Router"] --> Workspaces["Per-Worktree Mirrors\n(<repo>--wt-<hash>)"]
            Workspaces --> PrimarySalsa["Primary Salsa DB\n(rust-analyzer in-proc; child LSPs)"]
            Workspaces --> ShadowValidation["Isolated Shadow Engines\n(RAM-disk validation without cache poison)"]
            Workspaces --> RemoteExec["Remote Builds, Lints & Tests\n(cargo, go, pytest, swift, etc.)"]
            GatewayInternals --> Telemetry["Prometheus Scrape (:9401)\n& Pushgateway (:9091)"]
        end
    end

    Telemetry --> Monitoring["Prometheus + VictoriaMetrics + Grafana"]
Loading

prod-code separates the lightweight developer interface from heavy language intelligence and compilation:

  1. Mirroring over Mounting: Workspaces synchronize fast Base64 diffs over 10 GbE LAN instead of network-mounting filesystems (NFS/SSHFS), keeping filesystem operations local and fast.
  2. Worktree Isolation: Rust worktree mirrors attach isolated overlays to a shared base compiler database (SharedWorkspace::with_base), while child language servers run isolated per-process, avoiding cross-session state corruption.
  3. Dual-Engine Shadow Validation: Code edits are verified on dedicated shadow engines in memory before writing to disk, ensuring speculative proposals cannot invalidate warm primary caches.
  4. Polyglot Cluster Gossip: Nodes discover each other via UDP gossip on :9401, evaluate load and memory pressure, and route requests to capable nodes (including automatic rerouting of Swift subprojects to macOS nodes).

Requirements

Building prod-code and running its development checks require Rust 1.95.0 or newer. With rustup, install the supported minimum and the check components with:

rustup toolchain install 1.95.0 --profile minimal -c rustfmt -c clippy

Run commands with cargo +1.95.0 to use that toolchain without changing your default.

Install

Direct Download & Packages

Choose your preferred installation method for the prod-code CLI:

# Direct shell installer (detects OS and architecture)
curl -fsSL https://prod.codes/install.sh | sh

# Debian / Ubuntu (.deb)
curl -fsSLO https://github.com/alex09x/prod-code/releases/download/v0.3.29/prod-code_0.3.29_amd64.deb
sudo dpkg -i prod-code_0.3.29_amd64.deb

# RHEL / Fedora / Rocky Linux (.rpm)
sudo rpm -i https://github.com/alex09x/prod-code/releases/download/v0.3.29/prod-code-0.3.29-1.x86_64.rpm

# Arch Linux (.pkg.tar.gz)
sudo pacman -U https://github.com/alex09x/prod-code/releases/download/v0.3.29/prod-code-0.3.29-1-x86_64.pkg.tar.gz

# Build from source
cargo install --path crates/prod-code-client

Native notarized macOS installers (prod-code-0.3.29-macOS.pkg and .dmg) and standalone binaries for Linux (x86_64, aarch64) and macOS (arm64 Apple Silicon) are available on GitHub Releases.

In-Place Self-Updater

Keep your client installation up to date with a single command:

prod-code update --check   # check for newer releases on GitHub
prod-code update           # download, verify SHA-256 integrity, and replace binary in-place

When prod-code is updated, running agent sessions automatically pick up new MCP tools without requiring an IDE or agent restart (dynamic re-exec on binary change via MCP notifications/tools/list_changed).

Registering with AI Coding Agents

Register prod-code once; every repository accessed by your agent gains remote code intelligence tools:

# Claude Code
claude mcp add --scope user prod-code -e "PROD_CODE_REMOTE=192.0.2.10:9400" -- prod-code mcp

# OpenAI Codex CLI
codex mcp add prod-code --env "PROD_CODE_REMOTE=192.0.2.10:9400" -- prod-code mcp

# Gemini CLI
gemini mcp add -s user prod-code prod-code mcp -e "PROD_CODE_REMOTE=192.0.2.10:9400"

For Google Antigravity, add the server definition to ~/.gemini/config/mcp_config.json (or use ~/.gemini/settings.json for Gemini CLI):

{
  "mcpServers": {
    "prod-code": {
      "command": "prod-code",
      "args": ["mcp"],
      "env": {
        "PROD_CODE_REMOTE": "192.0.2.10:9400"
      }
    }
  }
}

Running the Gateway Daemon

On a Linux or macOS build node:

# Start gateway server directly
prod-code-server --bind 0.0.0.0:9400 --storage /srv/prod-code/workspaces \
  --advertise 192.0.2.10:9400 --peers 192.0.2.11:9400,192.0.2.12:9400

# Or run with declarative gateway.toml
prod-code-server --config /etc/prod-code/gateway.toml

In an editor

prod-code lsp is an editor's language server. The language's own server (rust-analyzer, gopls, clangd, basedpyright, the TypeScript server, sourcekit-lsp) runs on the node, started for the editor's session in the node's copy of the checkout, and the bridge carries the protocol both ways:

  • The editor's settings, rust-analyzer's check on save and the server's protocol extensions work as they do with a local server.
  • A save reaches the node before the server hears of it.
  • Files the server points at that exist only on the node (the standard library, dependency caches, generated files) are mirrored read-only under the user's cache directory.
  • --language picks the server for one language of a mixed checkout.

For Zed there is an extension in editors/zed. Or point Zed's own rust-analyzer at prod-code lsp --language rust, which keeps everything Zed wires to rust-analyzer.

What it gives an agent

Tools use the node that holds the workspace. The tables describe current source; check CHANGELOG.md for the version that contains a change.

Find code

tool what it does
code_search find code by natural language query; ranked declarations with matching doc comments (dense embeddings fused with lexical ranking)
code_symbols workspace symbol index by name, fuzzy matching, analyzer-backed
code_definition · code_references exact symbol definition location; every reference and usage across the workspace
code_callers · code_callees · code_implementations · code_supertypes call hierarchy in both directions as a tree to requested depth; trait/interface implementations, and supertypes or required traits
code_outline declaration outline with kinds and line numbers for a single file or every source file in a directory
code_source read stdlib, crate/package registry and SDK sources that live cached only on the gateway node
code_structural_search AST pattern search across polyglot languages using metavariables ($name) without brittle regex
code_find_duplicates clone and duplicate block detection across workspace files using Type-1 and Type-2 AST hashing

Understand it without reading everything

tool what it does
code_slice bounded transitive traversal of declarations referenced by a symbol; depth and byte budgets limit result size
code_hover · code_type_at signature, precise inferred type, documentation, and markdown hover information
code_impact blast radius of uncommitted changes: changed functions, reachable callers, and candidate tests
code_dependencies workspace dependency graph analysis, direct and transitive dependencies, coupling metrics, and cycle detection
code_dead_code reference-based unreferenced candidate declarations, marking unverified and protected symbols
code_prune_orphans eligible dead-code candidates removed with safe delete and analyzer validation; unverified and protected symbols remain

Change it safely

Most custom planners below target Rust. The parameter, move, extract-function, wrap-return, and OOP refactoring tools also support Go, C/C++, TypeScript/JavaScript, Python, and Swift for their documented input shapes. Rename and server code actions depend on the selected language server. See ROADMAP-AUDIT.md for missing capabilities and ROADMAP.md for individual restrictions.

Analyzer diagnostics do not include every compiler or borrow-checker check. Tools with verify: "compile" can additionally run a shadow compiler check; semantic refusals still apply. A Rust file reported as unlinked-file is unchecked and cannot pass edit validation. New modules must be checked with their module declarations; new Cargo targets need a workspace reload or an explicit compiler check that includes them. Missing or malformed diagnostic reports also fail validation. Manifest and lockfile proposals need code_shadow_run with the appropriate parser or build command; JSON manifests, Markdown documentation, and SVG vector graphics are validated directly through built-in syntax parsers.

tool what it does
code_validate_edit · code_validate_edits in-memory analyzer diagnostics and syntax validation for proposed contents across one or many files before writing; detects broken references and schema violations
code_diagnostics diagnostics for a file, in memory, without running a full build
code_rename · code_safe_delete semantic rename across the workspace (a field with its accessors, with accessors); delete declaration only when zero references exist, or parameter with arguments
code_change_signature Rust signature changes; Go reorder/removal through gopls and typed literal additions to ordinary functions with compiler checks
code_move a declaration moved to another module across languages, with imports it takes and leaves behind
code_move_method · code_move_module a method moved to the type of one of its parameters; a whole module moved to another parent with all referencing paths
code_extract_function a selection extracted into a named function across languages, replacing identical duplicates across files
code_introduce_parameter_object parameters bundled into a struct, dataclass, or object across callers and body uses
code_extract_parameter · code_inline_parameter promote an expression to a parameter; inline a uniform constant parameter into the body
code_migrate_type change a declared type, listing all incompatible sites before execution, with automatic .into() insertion
code_generify turn a parameter's concrete type into a bounded generic type parameter, verifying callers against the new signature
code_invert_boolean invert a boolean predicate, variable, or field, rewriting all conditions with identical runtime semantics
code_make_static · code_convert_to_method turn a method that never uses self into an associated function; turn an associated function into a method
code_extract_delegate move cohesive fields and methods to a helper delegate struct, updating accessors and instantiations
code_extract_trait · code_extract_interface extract inherent methods into a trait or interface definition across languages with caller imports
code_loop_to_iterator transform accumulator loops into idiomatic functional iterator chains across languages
code_introduce_variable bind repeated expression once (let w1 = expr;) and replace occurrences safely
code_wrap_return wrap return type in Option, Result, or Promise, adding ? or await at propagating callers
code_extract_field · code_encapsulate_field turn an expression into a struct field; encapsulate a public field with getters/setters
code_schema_rename rename a database/serialization schema field across multi-language models
code_assists · code_assist list and apply analyzer code actions, quick fixes, and compiler suggestions directly to checkout
code_codemod structural search and replace on syntax trees (pattern ==>> replacement), as diff or applied
code_generate_fixture synthesize valid typed test fixtures and builders from struct definitions with default fallbacks
code_propose_expression synthesize valid in-scope expressions evaluating to a requested target type
code_pull_up · code_push_down pull members up to a superclass/trait or push members down to subclasses/implementors
code_replace_constructor_with_factory replace direct constructor calls with named static factory methods
code_replace_constructor_with_builder transform multi-parameter constructors into fluent builder patterns
code_replace_inheritance_with_delegation refactor class inheritance hierarchies into composition and delegation
code_replace_conditional_with_polymorphism replace switch/match/if-else conditionals with polymorphic dispatch
code_shadow_run test multiple hypotheses in isolated RAM-disk workspaces concurrently and return the winning diff

Run it

tool what it does
code_check · code_lint · code_test · code_benchmarks compile check, lint, test, and benchmark on the node with parsed diagnostics; path narrows scope; fix: true applies compiler fixes
code_exec execute any build or toolchain command in remote workspace copy; modified files, formatters, and lockfiles are written back
code_diagnose_failure run tests and generate diagnostic failure dossiers with sites, callers, changes, and printed assertion operands

Operate it

tool what it does
code_status · code_sync gateway health, registered engines, loaded workspaces, and running builds/tests; manual delta sync push or pull
code_report_issue report a bug or missing feature directly to GitHub with sanitized diagnostics and automated issue deduplication

Every position tool also takes symbol instead of a file and a position, so an agent never has to grep for a line number:

{ "name": "code_callers", "arguments": { "symbol": "Metrics::record" } }

The same surface exists as a CLI for humans and scripts: prod-code search | slice | codemod | fixture | change-signature | schema-rename | migrate-type | move | move-method | move-module | parameter-object | extract-parameter | extract-field | encapsulate-field | wrap-return | make-static | convert-to-method | inline-parameter | introduce-variable | extract-trait | extract-interface | extract-delegate | pull-up | push-down | replace-constructor-with-factory | replace-constructor-with-builder | replace-inheritance-with-delegation | replace-conditional-with-polymorphism | prune | loop-to-iterator | invert-boolean | generify | hover | def | refs | callers | callees | impls | supertypes | symbols | outline | validate | diagnostics | check | lint | test | benchmarks | exec | impact | diagnose | rename | assists | assist | safe-delete | dead-code | dependencies | duplicates | structural-search | propose-expression | shadow-run | source | status | cluster | resolve | sync | pull | update | package | cert | metrics. The position commands take --symbol NAME instead of a file and a position, prod-code symbols <name> finds a declaration by name, and prod-code validate FILE --from NEW --with OTHER=NEW2 checks a multi-file change in one overlay.

Three things worth seeing

Ask a question in words. The gateway indexes every declaration with the doc comment above it and ranks them against your question. When embeddings are available, dense ranking is fused with lexical ranking; otherwise the response identifies lexical-only search.

$ prod-code search "how do we decide which node runs a workspace"
10 hit(s) in 16 ms (1010 declarations, 40 files)

 1. [function] pick_node  crates/prod-code-mcp/src/cluster.rs:107
    Chooses the gateway for `workspace_name` among `nodes`: the remembered placement when it
    is still one of the nodes, alive and able to serve `engine`, otherwise the quietest node

Read a symbol without reading its files. code_slice follows the analyzer's own edges from a declaration within the requested budgets. It returns whole declarations, without intra-function data-flow analysis.

$ prod-code slice crates/prod-code-gateway/src/shadow.rs --line 469 --depth 1
slice of `run_shadow`: 10 item(s), 11474 bytes from 284105 bytes of source (96% smaller)

Try three fixes at once. Each candidate runs in an overlay of the workspace mounted at the workspace's own path, so the warm target/ stays valid and nothing touches your checkout.

$ prod-code shadow-run spec.json -- cargo test
  plus      exit 0     in 0.4s  2 passed, 0 failed  <- winner
  clamp     exit 0     in 0.4s  2 passed, 0 failed
  baseline  exit 101   in 0.0s  0 passed, 2 failed
  mul       exit 101   in 0.4s  0 passed, 2 failed

How it works

The checkout is mirrored, not mounted. First contact sends a manifest of paths, sizes and hashes; the gateway seeds a new worktree from the origin repository's copy and asks only for what is missing (0.4 s instead of ~7 s for a 10 MB repository). After that the client keeps a watermark per node and sends a diff. Content travels base64, which took a 10.8 MB first sync from 8.1 s to 0.76 s. The MCP server watches the tree and syncs only when something changed.

Worktree isolation with shared base analysis. Each git worktree receives its own server workspace directory named <repo>--wt-<hash>. In Rust, worktrees attach isolated session overlays to a shared base compiler database (SharedWorkspace::with_base), keeping memory usage bounded while preventing cross-session bleed. Child language servers run isolated per-process. The engine stays resident until idle for thirty minutes (--idle-evict-secs), and worktree directories are pruned after seven days (--prune-worktree-days or prune_worktree_secs = 604800).

Proposals are checked on a second analyzer. Validating an edit opens the proposed text in the analyzer and closes it again; in the analyzer every other query uses, a proposal that changes what a widely imported file declares made the next query re-infer the crate (21 s for a references after a dry run). Validation sessions run on a second engine for the same workspace, fed by every sync like the first, so a dry run never reaches anyone else's query. It costs the memory of one more database per workspace that has been validated.

Dual-engine shadow validation: speculative edits tested without cache poisoning

Builds and tests run on the node, in the workspace's own target/, which stays warm between runs. Files a command changes are written back into your checkout.

Several nodes. Gateways gossip every 5 s; a client needs one seed address. A checkout is placed on the node that already holds it, otherwise on the quietest one that serves its language. --engines rust,go restricts a node to what it should serve, so a macOS node can be Swift-only and placement never sends Rust work to a workstation. A request that names a path in a nested project of another language — code_test {path: "swift"} in a Rust repository with a SwiftPM package under swift/ — goes to a node that serves that language, placed under its own key so the checkout's own placement stays. Nodes given with --remote on the command line are used as given, without asking the cluster.

Production cluster: 9 nodes, 355 cores, language-aware routing

$ prod-code cluster
⚡ prod-code cluster (9 node(s) · 355 cpus)
192.0.2.10:9400   UP   load 0.05/cpu (128 cpus)  workspaces 3   rss 482 MB  [linux/aarch64]
                  engines: rust, go, cpp, python, typescript, java, kotlin, csharp, scala, zig, nim, d, php, ruby, dart
192.0.2.11:9400   UP   load 0.12/cpu (32 cpus)   workspaces 2   rss 310 MB  [linux/x86_64 Zen5]
                  engines: rust, go, cpp, python, typescript
192.0.2.12:9400   UP   load 0.08/cpu (32 cpus)   workspaces 1   rss 280 MB  [linux/x86_64 Zen4]
                  engines: rust, go, cpp, python, typescript
192.0.2.13:9400   UP   load 0.15/cpu (32 cpus)   workspaces 4   rss 415 MB  [linux/x86_64]
                  engines: rust, go, cpp, python, typescript, java, kotlin, csharp, scala, zig, nim, d, php, ruby, dart
192.0.2.14:9400   UP   load 0.04/cpu (32 cpus)   workspaces 1   rss 195 MB  [linux/x86_64]
                  engines: rust, go, cpp, python, typescript
192.0.2.15:9400   UP   load 0.06/cpu (32 cpus)   workspaces 0   rss 160 MB  [linux/x86_64]
                  engines: rust, go, cpp, python, typescript
192.0.2.16:9400   UP   load 0.07/cpu (32 cpus)   workspaces 0   rss 155 MB  [linux/x86_64]
                  engines: rust, go, cpp, python, typescript
192.0.2.17:9400   UP   load 0.18/cpu (24 cpus)   workspaces 2   rss 290 MB  [darwin/arm64 Mac Studio]
                  engines: swift, go, rust, typescript
192.0.2.18:9400   UP   load 0.22/cpu (11 cpus)   workspaces 1   rss 210 MB  [darwin/arm64 MacBook Pro]
                  engines: swift

What each language gets

Rust Go C/C++ TypeScript/JavaScript Python Swift
engine rust-analyzer in-process gopls clangd TypeScript 7 native LSP basedpyright sourcekit-lsp (macOS node)
hover / def / refs / symbols / callers / callees / impls yes yes yes yes yes yes
rename yes (+ module files) yes yes yes yes yes
server code actions yes server-dependent server-dependent server-dependent server-dependent server-dependent
safe-delete yes - - - - -
custom signature changes yes named-parameter permutations - - - -
extract parameter / parameter object supported shapes supported shapes supported shapes supported shapes supported shapes supported shapes
check cargo check go build cmake / meson / make tsc (bunx / pnpm / yarn / npx) basedpyright (uv / .venv aware) swift build / xcodebuild
lint clippy go vet - eslint / biome ruff -
test cargo test go test ctest / meson test vitest / jest / bun test / mocha pytest / unittest swift test / xcodebuild test

code_search and code_slice work on all six. Tooling is detected from the checkout (lock files, package.json, pyproject, CMakeLists…). Dependencies live on the node: run prod-code exec -- bun install, -- uv sync or -- npm ci once per checkout and the language servers and test runners use them.

Configuration

Gateway Server (gateway.toml)

The gateway daemon discovers its configuration file automatically from the following locations (highest to lowest priority):

  1. Explicit CLI argument: --config /path/to/gateway.toml
  2. System configuration: /etc/prod-code/gateway.toml
  3. User XDG configuration: ~/.config/prod-code/gateway.toml
  4. Home directory: ~/.prod-code/gateway.toml
  5. Current working directory: ./gateway.toml

CLI flags and environment variables always override values specified in gateway.toml.

[server]
# Network bind address for RPC connections (default: 0.0.0.0:9400)
bind = "0.0.0.0:9400"

# Optional Unix domain socket path
# socket_path = "/run/prod-code/gateway.sock"

# Workspace storage root directory on server
storage = "/srv/prod-code/workspaces"

# Advertised host:port for gossip peers and clients
advertise = "192.0.2.10:9400"

# Cluster peer addresses for gossip discovery
peers = "192.0.2.11:9400,192.0.2.12:9400"

# Languages served (empty array serves all installed language engines)
engines = ["rust", "go", "cpp", "python", "typescript"]

# Unload idle engines after this many seconds (0 disables, default: 1800)
idle_evict_secs = 1800

# Retain git worktree mirrors for this many seconds (default: 3600; 604800 = 7 days)
prune_worktree_secs = 604800

# RAM-disk build cache (/dev/shm) for high-throughput compilation
build_cache_ram = false

[metrics]
enabled = true
snapshot_interval_secs = 30
inventory_interval_secs = 3600

[metrics.retention]
retention_days = 14
max_storage_bytes = 524288000   # 500 MB budget for metrics logs

[metrics.prometheus]
enabled = true
mode = "scrape"                 # "scrape" (pull HTTP endpoint), "push" (Pushgateway), or "both"
listen = "0.0.0.0:9401"         # Serves GET /metrics and GET /health
# push_url = "http://192.0.2.20:9091"
push_interval_secs = 15
job = "prod-code"

Per-Repository Options (prod-code.toml)

Put a prod-code.toml at the checkout root to tune how the gateway analyses your repository. It is mirrored like any manifest and evaluated when the workspace loads:

[rust]
features = "all"            # or ["feat-a", "feat-b"]; default: the crate's default features
no_default_features = false
all_targets = true          # tests, benches, and examples are analysed (default: true)
sysroot = true              # standard library from rust-src (default: true)

Use features = "all" when the same module tree is compiled into several crates behind feature flags: rust-analyzer attaches each file to one crate, and a module behind a disabled feature is otherwise dead there.

Environment Variables

The client and gateway respect the following environment variables:

Variable Scope Description
PROD_CODE_REMOTE Client Remote gateway address(es) (host:port[,host:port...]), defaults to 127.0.0.1:9400. Rendezvous hashing picks the target node with automatic failover.
PROD_CODE_AUTH_TOKEN Client / Gateway Shared bearer authentication token for secure RPC connections across untrusted networks.
PROD_CODE_ENGINES Gateway Comma-separated list of engines the node is permitted to serve (e.g. swift on macOS nodes, rust,go on Linux).
PROD_CODE_SIGN_IDENTITY Gateway (macOS) Developer ID / ad-hoc signing identity for macOS gateway daemons to preserve Local Network permissions across updates.
PROD_CODE_LOCAL Build Hook Optional escape hatch bypassing the local-build guard hook (prod-code-local-build-guard.py) for commands that must compile locally.

Operating & Fleet Management

Cluster Rollout. Deploy binary updates across the cluster using the rollout script:

# Copy local binary to cluster nodes, restart systemd service, and verify versions
python3 scripts/cluster-rollout.py --version 0.3.29

# Or run the shell orchestrator
scripts/cluster-rollout.sh --version 0.3.29

The script locates the compiled binary locally, copies it via scp to each node sequentially, restarts the prod-code-gateway service, and checks systemctl is-active and prod-code-server --version to verify the deployment.

Prometheus & VictoriaMetrics Telemetry. Gateways export native metrics for Grafana dashboards:

  • HTTP Scrape Endpoint: http://<node>:9401/metrics exposes Prometheus exposition format metrics (CPU, RSS memory, cache hit rates, query latencies, active Salsa engines).
  • Health Probes: http://<node>:9401/health returns 200 OK as an HTTP listener liveness probe.
  • Pushgateway: Configure mode = "push" or mode = "both" in gateway.toml to stream telemetry directly to a central Prometheus Pushgateway.
  • Event Audit Ledger: Every query, command, and sync round appends an audit event to <storage>/../metrics/events-YYYY-MM-DD.jsonl. Analyze aggregate latency and usage across the cluster with prod-code metrics [--since SECS].

macOS Nodes. scripts/deploy-mac-node.sh <host> <advertise> <peers> builds or installs the gateway, signs it with PROD_CODE_SIGN_IDENTITY under a stable bundle identifier (so macOS remembers the Local Network permission across updates), writes the launchd agent with --engines (PROD_CODE_ENGINES, default swift), and reloads the service.

Field Evaluations & Benchmarks

We evaluate prod-code against prominent real-world open-source repositories using our standardized 67-tool evaluation protocol across cluster nodes (0% CPU on developer laptop):

Repository Stack Tested Tools Cold Sync LAN Latency Deep-Dive Report
BurntSushi/ripgrep Rust (32-core node) 67 / 67 tools (AST search, slicing, 30 refactorings, RAM validation) 45.4 KB (27 files) 1.02 ms RTT Can 67 AST Tools Break Ripgrep? →
quickwit-oss/tantivy Rust (32-core node) 67 / 67 tools (10-crate DAG, 18-file rename, clone detection, AST search) 6.77 MB (602 files) 0.96 ms RTT 7,156 Cyclic Module Paths in Tantivy →
tokio-rs/tokio Rust (32-core node) 67 / 67 tools (10-crate circular DAG, AST slicing, Issue #736 fix, Criterion bench) 6.11 MB (882 files) 0.63 ms RTT Six Circular Dependencies in Tokio →
pola-rs/polars Rust (32-core node) 67 / 67 tools (33-crate DAG, Issue #737 fix, AST slicing, RAM validation) 29.6 MB (3,426 files) 0.56 ms RTT Half a Million Lines of Arrow →
astral-sh/uv Rust (32-core node) 67 / 67 tools (74-crate DAG, 347 clones, Issue #738 fix, AST slicing) 36.5 MB (1,787 files) 0.50 ms RTT 347 Code Clones Inside uv →
bevyengine/bevy Rust (32-core node) 67 / 67 tools (97-crate DAG, 204 clones, Issue #739 fix, AST slicing, 28 traits on Entity) 81.0 MB (3,044 files) 0.61 ms RTT 204 Code Clones and Two Self-Loops in Bevy →
prometheus/prometheus Go (32-core node) 67 / 67 tools (84-package DAG, 1,485 error checks, Issue #740 fix, 99% slicing) 385K lines (736 files) 0.86 ms RTT 1,485 Error Checks and Zero Import Cycles in Prometheus →
kubernetes/kubernetes Go (32-core node) 67 / 67 tools (779-pkg DAG, 900+ clones, Issues #741 & #742 fixes, full Go refactoring suite) 5.38M lines (17,823 files) 0.74 ms RTT 5.3 Million Lines of Go in Kubernetes →
etcd-io/etcd Go (32-core node) 67 / 67 tools (1,094-pkg DAG, zero cycles, 445 error returns, MoveLeader slice, interface guards) 220K lines (1,094 files) 0.65 ms RTT etcd Under the Microscope →
django/django Python (32-core node) 67 / 67 tools (25 circular checks, 150+ clones, basedpyright diagnostics, full Python refactoring) 527K lines (2,932 files) 0.65 ms RTT Half a Million Lines of Python Inside Django →
psf/black Python (32-core node) 67 / 67 tools (concurrency cycle, 10-line version clones, 12-callsite parameter bundling, 99.8% slice) 135K lines (358 files) 0.93 ms RTT Black Under the Microscope →
tiangolo/fastapi Python (32-core node) 67 / 67 tools (135 OpenAPI clones, 66 error guards, 99.8% dependency slice, parameter bundling) 118K lines (1,166 files) 0.93 ms RTT FastAPI Under the Microscope →
pallets/flask Python (32-core node) 67 / 67 tools (blueprint clones, 159 error guards, 98.6% dispatch slice, dataclass bundling) 18K lines (83 files) 0.65 ms RTT Flask Under the Microscope →
moby/moby Go (32-core node) 67 / 67 tools (224 varint clones, 858 error guards, 99.9% ContainerStart slice, interface safety refusal) 388K lines (2,269 files) 0.65 ms RTT Moby Under the Microscope →
microsoft/TypeScript TypeScript (32-core node) 67 / 67 tools (264K decls, 17 AST factory clones, 99.9% createSourceFile slice, interface synthesis) 31,433 files 0.65 ms RTT TypeScript Under the Microscope →
facebook/react JavaScript/TS (32-core node) 67 / 67 tools (Fiber work loop slice, 18 test clones, 156 error throws, compiler generic guardrails) 745K lines (4,445 files) 0.65 ms RTT React Under the Microscope →
vercel/next.js TypeScript/JS (32-core node) 67 / 67 tools (SSR render slice, 484 clone groups, 1,254 error assertions, cross-file boolean inversion) 1.29M lines (24,309 files) 0.65 ms RTT Next.js Under the Microscope →
expressjs/express JavaScript (32-core node) 67 / 67 tools (95% app.handle slice, 10 TypeError sites, Clone Group #150, dynamic receiver guardrails) 21.5K lines (201 files) 0.65 ms RTT Express Under the Microscope →
redis/redis C (32-core node) 67 / 67 tools (event loop slice to epoll_wait, 454 error reply sites, Clone Group #382, non-call guards) 212K lines (219 files) 0.65 ms RTT Redis Under the Microscope →
duckdb/duckdb C++ (32-core node) 67 / 67 tools (QueryResult slice, 2,277 InternalException sites, 5,500+ clone groups, Catch2 guards) 681K lines (3,273 files) 0.65 ms RTT DuckDB Under the Microscope →
git/git C (32-core node) 67 / 67 tools (setup_git_directory in 316 ms, 4,657 error exit points, Clone Group #199, multi-file codemods) 443K lines (986 files) 0.65 ms RTT Git Under the Microscope →
curl/curl C (32-core node) 67 / 67 tools (Curl_easy centrality 4.83, 1,924 error/telemetry points, Clone Group #780, parameterized codemod) 200K lines (1,048 files) 0.61 ms RTT curl Under the Microscope →
apple/swift-algorithms Swift (macOS node) 67 / 67 tools (Chain2Sequence graph, 81 bounds invariants, Clone Group #314, remote test offload) 13.7K lines (56 files) 5.44 ms RTT Swift Algorithms Under the Microscope →
apple/swift-argument-parser Swift (macOS node) 67 / 67 tools (ParsableCommand in-degree 296, 64 error egress points, property wrapper clones, 81 tests offloaded) 30.0K lines (121 files) 5.44 ms RTT Swift Argument Parser Under the Microscope →
Alamofire/Alamofire Swift (macOS node) 67 / 67 tools (SessionDelegate multiplexer, 92 error boundaries, 20 clone groups, remote test offload) 39.2K lines (102 files) 5.44 ms RTT Alamofire Under the Microscope →
apple/swift-collections Swift (macOS node) 67 / 67 tools (Deque ring buffer, 1,279 boundary invariants, Clone Group #1165, 130 tests offloaded) 71.0K lines (391 files) 5.44 ms RTT Swift Collections Under the Microscope →
google/guava Java (32-core node) 67 / 67 tools (795K lines, 33-occurrence clone analysis, 3,279 files, 545.82 ms search, refactoring guardrails) 795K lines (3,279 files) 0.65 ms RTT Guava Under the Microscope →
spring-projects/spring-boot Java (32-core node) 67 / 67 tools (880K lines, 448 modules, 2,790 deps DAG, 55 autoconfig clones, 982 AST matches, cluster JDTLS 0 errors) 880K lines (8,696 files) 0.65 ms RTT Spring Boot Under the Microscope →
apache/kafka Java/Scala (32-core node) 67 / 67 tools (1.7M lines, 64-module DAG, 125-occurrence equals() clones, 847 AST matches, cluster JDTLS 0 errors) 1.72M lines (6,475 files) 0.49 ms RTT Kafka Under the Microscope →
netty/netty Java (32-core node) 67 / 67 tools (652K lines, 61 modules, all→bom cycle, 510 Huffman clones, multi-site refactoring, cluster JDTLS 0 errors) 652K lines (3,595 files) 3.43 ms RTT Netty Under the Microscope →
ktorio/ktor Kotlin (32-core node) 67 / 67 tools (296K lines, 134 Gradle modules, 100 test cycles, 74 coroutine clones, cluster kotlin-language-server 0 errors) 296K lines (2,423 files) 1.97 ms RTT Ktor Under the Microscope →
Kotlin/kotlinx.coroutines Kotlin (32-core node) 67 / 67 tools (113K lines, 25 modules clean DAG, 32 TestBase clones, 72 AST matches, cluster kotlin-language-server 0 errors) 113K lines (1,039 files) 1.97 ms RTT Kotlinx.coroutines Under the Microscope →
detekt/detekt Kotlin (32-core node) 67 / 67 tools (132K lines, 41 modules, 4 test cycles, 288 lint clones, 58 AST matches, cluster kotlin-language-server 0 errors) 132K lines (1,105 files) 1.97 ms RTT Detekt Under the Microscope →
arrow-kt/arrow Kotlin (32-core node) 67 / 67 tools (73K lines, 38 modules, 5 core cycles, 27 Either clones, Raise DSL search, cluster kotlin-language-server 0 errors) 72.9K lines (757 files) 1.97 ms RTT Arrow Under the Microscope →
dotnet/aspnetcore C# (32-core node) 67 / 67 tools (1.76M lines, 625 projects, 7,427 deps, 20 clone groups, 4K+ guard modernizations, cluster OmniSharp 0 errors) 1.76M lines (10,685 files) 1.55 ms RTT ASP.NET Core Under the Microscope →
dotnet/efcore C# (32-core node) 67 / 67 tools (1.75M lines, 58 projects clean DAG, 20 clone groups, 1.4K guard search, cluster OmniSharp 0 errors) 1.75M lines (5,778 files) 0.55 ms RTT EF Core Under the Microscope →
dotnet/roslyn C# (32-core node) 67 / 67 tools (6.5M lines, 394 projects, 2,103 deps, 1.8% clones, 15.3K invariants, cluster OmniSharp 0 errors) 6.50M lines (18,176 files) 0.55 ms RTT Roslyn Under the Microscope →
dotnet/BenchmarkDotNet C# (32-core node) 67 / 67 tools (121K lines, 29 projects clean DAG, 20 clone groups, 1.1K benchmarks, cluster OmniSharp 0 errors) 121K lines (1,175 files) 0.58 ms RTT BenchmarkDotNet Under the Microscope →
apache/spark Scala (32-core node) 67 / 67 tools (2.05M lines, 52 modules clean DAG, 0.7% clones, 40K assertions, cluster Metals 0 errors) 2.05M lines (6,448 files) 0.95 ms RTT Spark Under the Microscope →
apache/incubator-pekko Scala (32-core node) 67 / 67 tools (838K lines, 41 modules clean DAG, 3.5% clones, 435 preconditions, cluster Metals 0 errors) 838K lines (3,384 files) 0.95 ms RTT Pekko Under the Microscope →
playframework/playframework Scala (32-core node) 67 / 67 tools (222K lines, 44 modules clean DAG, 0.9% clones, 133 preconditions, cluster Metals 0 errors) 222K lines (1,636 files) 0.95 ms RTT Play Under the Microscope →
scalameta/scalameta Scala (32-core node) 67 / 67 tools (106K lines, 24 modules clean DAG, 2.7% clones, 202 @ast nodes, cluster Metals 0 errors) 106K lines (722 files) 0.95 ms RTT Scalameta Under the Microscope →
ziglang/zig Zig (32-core node) 67 / 67 tools (1.36M lines, 2,052 codegen clones, 480 compiler errdefers, 4.2K asserts, cluster ZLS 0 errors) 1.36M lines (2,950 files) 0.44 ms RTT Zig Under the Microscope →
ghostty-org/ghostty Zig (32-core node) 67 / 67 tools (363K lines, 107 VT clones, 8.8K defers, 766 asserts, cluster ZLS 0 errors) 363K lines (807 files) 0.44 ms RTT Ghostty Under the Microscope →
tigerbeetle/tigerbeetle Zig (32-core node) 67 / 67 tools (157K lines, 22 VSR frames, 8,251 asserts, 0 runtime allocs, cluster ZLS 0 errors) 157K lines (244 files) 0.25 ms RTT TigerBeetle Under the Microscope →
zigtools/zls Zig (32-core node) 67 / 67 tool calls attempted; Zig dependency graph unsupported (56K lines, 5 completion clones, 86 errdefers, in-memory ZLS pre-flight) 56K lines (90 files) 0.46 ms RTT ZLS Under the Microscope →
nim-lang/Nim Nim (32-core node) 67 / 67 tool calls attempted; Nim dependency graph unsupported (461K lines, allocator test clones, 1.8K asserts, 94% AST slice reduction) 461K lines (3,923 files) 0.68 ms RTT Nim Under the Microscope →
status-im/nimbus-eth2 Nim (32-core node) 67 / 67 tool calls attempted; Nim dependency graph unsupported (180K lines, hard-fork clones, 585 Result types, zero-exception safety) 180K lines (379 files) 0.63 ms RTT Nimbus Under the Microscope →
nim-lang/nimble Nim (32-core node) 67 / 67 tool calls attempted; Nim dependency graph unsupported; 6-line clone threshold is nonstandard (39K lines, SAT solver & PubGrub, 136 test fixtures, compiler AST parser) 38.9K lines (135 files) 0.58 ms RTT Nimble Under the Microscope →
dlang/dmd D (32-core node) 67 / 67 tool calls attempted; D dependency graph and extract-function unsupported (976K lines, ImportC C11 AST parser, 12K invariants, CTFE interpreter) 976K lines (5,579 files) 0.58 ms RTT DMD Under the Microscope →
dlang/phobos D (32-core node) 67 / 67 tool calls attempted; D dependency graph and extract-function unsupported (366K lines, range pipeline architecture, 33K asserts, 5.6K unittests) 366K lines (186 files) 0.58 ms RTT Phobos Under the Microscope →
vibe-d/vibe.d D (32-core node) 67 / 67 tool calls attempted; D dependency graph and extract-function unsupported (30K lines, compile-time REST interface generator, 1.4K asserts) 30.2K lines (108 files) 0.58 ms RTT Vibe.d Under the Microscope →
laravel/framework PHP (32-core node) 67 / 67 tool calls attempted; PHP dependency graph unsupported (573K lines, IoC container reflection, 34K test asserts, Eloquent ORM) 573K lines (3,120 files) 0.58 ms RTT Laravel Under the Microscope →
symfony/symfony PHP (32-core node) 67 / 67 tool calls attempted; PHP dependency graph unsupported (2.20M lines, compiled DI container passes, 47.9K test asserts) 2.20M lines (11,999 files) 0.58 ms RTT Symfony Under the Microscope →
composer/composer PHP (32-core node) 67 / 67 tool calls attempted; PHP dependency graph unsupported (140K lines, Boolean SAT solver, 2.5K test asserts, 620 exceptions) 139.7K lines (634 files) 0.58 ms RTT Composer Under the Microscope →
WordPress/WordPress PHP (32-core node) 67 / 67 tool calls attempted; PHP dependency graph unsupported (674K lines, WP_Hook event dispatcher, 2.4K hook points, 3.7K error guards) 673.9K lines (1,899 files) 0.58 ms RTT WordPress Under the Microscope →
rails/rails Ruby (32-core node) 67 / 67 tool calls attempted; Ruby dependency graph and extract-function unsupported (573K lines, Active Record Relation AST, 60K test asserts, 1.4K exceptions) 573.5K lines (3,478 files) 0.58 ms RTT Rails Under the Microscope →
jekyll/jekyll Ruby (32-core node) 67 / 67 tool calls attempted; Ruby dependency graph and extract-function unsupported (23K lines, 6-stage compilation pipeline, 1.3K test asserts) 22.8K lines (162 files) 0.58 ms RTT Jekyll Under the Microscope →
mastodon/mastodon Ruby (32-core node) 67 / 67 tool calls attempted; Ruby dependency graph and extract-function unsupported (190K lines, ActivityPub JSON-LD verification, 8.2K RSpec asserts) 189.7K lines (3,278 files) 0.58 ms RTT Mastodon Under the Microscope →
Homebrew/brew Ruby (32-core node) 67 / 67 tool calls attempted; Ruby dependency graph and extract-function unsupported (371K lines, Sorbet typed strict, 12.4K test asserts, 2.2K exceptions) 371.1K lines (2,379 files) 0.58 ms RTT Homebrew Under the Microscope →
flutter/flutter Dart (32-core node) 67 / 67 tool calls attempted; Dart dependency graph and extract-function unsupported (2.60M lines, 10-phase render pipeline, 112.7K test asserts, 3.8K errors) 2.60M lines (6,554 files) 0.30 ms RTT Flutter Under the Microscope →
felangel/bloc Dart (32-core node) 67 / 67 tool calls attempted; Dart dependency graph and extract-function unsupported (46K lines, reactive event transformers, 1.6K test asserts, 72 errors) 45.7K lines (616 files) 0.35 ms RTT Bloc Under the Microscope →
cfug/dio Dart (32-core node) 67 tool calls attempted; dependency graph and extract-function unsupported (23K lines, FIFO interceptor chain, 845 test asserts, 138 exceptions) 22.8K lines (156 files) 0.32 ms RTT Dio Under the Microscope →
dart-lang/sdk Dart (32-core node) 67 / 67 tool calls attempted; Dart dependency graph and extract-function unsupported (5.74M lines, Kernel AST CFE compiler, 33.0K test asserts, 8.7K invariants) 5.74M lines (25,732 files) 0.35 ms RTT Dart SDK Under the Microscope →
neovim/neovim Lua (32-core node) 67 / 67 tool calls attempted; Lua dependency graph and extract-function unsupported (448K lines, built-in LSP client, 18.4K test asserts, 1.3K invariants) 448.2K lines (854 files) 0.35 ms RTT Neovim Under the Microscope →
openresty/lua-nginx-module C/Perl (32-core node) 67 tool calls attempted; C/Perl dependency graph and extract-function unsupported (224K lines, cosockets & execution contexts, 6.8K test asserts, 827 errors) 224.7K lines (434 files) 0.35 ms RTT OpenResty NGINX Module Under the Microscope →
luau-lang/luau C++/Luau (32-core node) 67 tool calls attempted; dependency graph and extract-function unsupported (534K lines, constraint solver & native codegen, 16.3K asserts, 1.8K invariants) 534.2K lines (1,533 files) 0.35 ms RTT Luau Under the Microscope →
elixir-lang/elixir Elixir (32-core node) 67 / 67 tool calls attempted; Elixir dependency graph and extract-function unsupported (390K lines, quoted-AST traversal, 18.0K test asserts, 633 exceptions) 390.1K lines (780 files) 0.35 ms RTT Elixir Under the Microscope →
phoenixframework/phoenix Elixir (32-core node) 67 / 67 tool calls attempted; Elixir dependency graph and extract-function unsupported (101K lines, generated route matching and socket routing, 3.2K test asserts, 198 exceptions) 101.0K lines (508 files) 0.35 ms RTT Phoenix Under the Microscope →
phoenixframework/phoenix_live_view Elixir (32-core node) 67 / 67 tool calls attempted; Elixir dependency graph and extract-function unsupported (142K lines, HEEx template compiler & diff engine, 3.5K test asserts, 215 exceptions) 142.2K lines (430 files) 0.35 ms RTT Phoenix LiveView Under the Microscope →
dashbitco/broadway Elixir (32-core node) 67 / 67 tool calls attempted; Elixir dependency graph and extract-function unsupported (10.3K lines, GenStage backpressure & dynamic batching, 435 test asserts, 18 exceptions) 10.3K lines (46 files) 0.35 ms RTT Broadway Under the Microscope →

Reading more

The design decisions, with the measurements behind them, are written up as a series: prod.codes/blog/series/prod-code — why the laptop is the wrong place for the analyzer, why worktrees cannot share a database, how the mirror stays current, why tools take a symbol instead of a position, validating an edit before writing it, where the milliseconds went, and running candidate fixes in overlay shadows.

In this repository: ROADMAP.md for what is built and what is not, CHANGELOG.md for what each release changed, docs/release-v0.3.29.md for the v0.3.29 architectural release overview and cluster offloading benchmarks, and CONTRIBUTING.md for how a change gets made here (an issue and a pull request with the commands that reproduce it; checks run on the build nodes, there is no hosted CI).

Author

Alexander Panasenko (@alex09x) — alex@prod.codes

Citation

If you use prod-code in academic work or research, please cite the archived release (v0.3.18):

@software{panasenko_2026_prodcode,
  author       = {Panasenko, Alexander},
  title        = {prod-code: Remote code intelligence for AI coding agents},
  month        = sep,
  year         = 2026,
  publisher    = {Zenodo},
  version      = {0.3.18},
  doi          = {10.5281/zenodo.23028285},
  url          = {https://doi.org/10.5281/zenodo.23028285}
}

See CITATION.cff for complete citation metadata.

License

Dual-licensed under either of:

at your option.

About

Remote code intelligence server for AI coding agents (MCP): rust-analyzer, gopls, clangd, pyright and TypeScript run on a LAN build node — semantic navigation, safe refactoring, edit validation, builds and tests without burning the laptop.

Topics

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages