Architecture
The canonical architecture document is docs/spec/01-architecture-overview.md. Read that for the full picture. This page is the short version every contributor needs to keep in head.
The crate split
versionx-coreis the brain. Everything mutating originates here.- Frontends (
versionx-cli,versionx-tui,versionx-daemon,versionx-web,versionx-mcp) are thin — they translate between a transport andversionx-core. - Adapters (
versionx-adapter-*) drive real ecosystem tools. They implement one trait. - Runtimes (
versionx-runtime-*) install language toolchains. They implement another trait. - Supporting crates (
versionx-config,-lockfile,-state,-policy,-release, etc.) are single-purpose libraries used by core.
Dependency rules (load-bearing)
versionx-coredepends only on: adapters, runtimes, config, lockfile, state, policy, release, tasks, multirepo, git, github, events.- Frontends depend on
versionx-core. They never import adapters, runtimes, or state directly. - Adapters depend only on
versionx-adapter-traitand common utility crates. Adapters never depend onversionx-core. One-way. - No frontend depends on another frontend.
These rules are enforced by cargo-deny config + architecture tests. Violating them is a CI failure.
Why the rules exist
- Clean core/frontend split → open-core monetization later is a clean boundary, not surgery.
- One-way adapter dep → adapters can be extracted to separate crates or repos at any time.
- No frontend-to-frontend → the TUI, CLI, MCP server are independently swappable.
Process model (short)
- Mode A — Direct. CLI → core → adapters. Used in CI,
--no-daemon, first run. ~20ms startup. - Mode B — Daemon-backed. CLI ↔ daemon ↔ core. Default interactive mode. Socket at
$XDG_RUNTIME_DIR/versionx/daemon.sock(or platform equivalent). ~1ms steady-state. - Mode C — Daemon + web + MCP. The daemon exposes HTTP and MCP over loopback in addition to the CLI socket.
Full diagram and trace of versionx sync end-to-end in the spec.
The library boundary
versionx-core is a stateless intent engine that produces and applies Plans. Frontends are prohibited from:
- Directly calling
gitor ecosystem tools. - Writing to the state DB without going through
versionx-state. - Reimplementing resolution or pinning logic.
If you find yourself reaching for Command::new("git") in a frontend, that's the signal that a helper belongs in versionx-git or versionx-core.
Transport surfaces
Every user-visible capability lives in versionx-core. Transports are thin.
- CLI (
versionx) —clapderive.--help-jsonemits the full command tree. - TUI (
versionx tui) —ratatui; reads state, fires the same core calls as CLI. - Daemon RPC — JSON-RPC 2.0 over UDS / named pipe. Methods map 1:1 to core.
- HTTP API — axum on loopback; OpenAPI via
aide. - MCP —
rmcp. Stdio + streamable HTTP. ~10 workflow-shaped tools.
See also
- Workspace tour — one paragraph per crate.
docs/spec/01-architecture-overview.md— the authoritative version.