Server Provisioning
September 18, 2026 ยท View on GitHub
The editor extension owns server provisioning. Users should be able to install
the extension, open a Rust/Cargo workspace, and get ripr diagnostics without
running cargo install ripr first.
Resolution Order
The VS Code/Open VSX extension resolves the server in this order:
1. ripr.server.path
2. bundled server binary, if present
3. downloaded cached server binary
4. verified first-run download from GitHub Releases
5. ripr on PATH
6. actionable error
ripr.server.path is an override for pinned or enterprise-managed binaries. The
PATH fallback remains useful for local development and offline installs.
Before activation commits to any candidate, the extension first checks
ripr --version, then runs a bounded standard-LSP compatibility session over
ripr lsp --stdio: framed initialize, initialized, shutdown, and exit.
Each response must use JSON-RPC 2.0, the active request id, and exactly one of a
structurally valid result or error. Initialize must identify a versioned
ripr server, select UTF-16, and advertise full saved synchronization, hover,
code actions, pull diagnostics, workspace folders, and the complete command set
the extension executes. Only code-action resolve and work-done progress remain
typed optional evidence because the client has fallbacks for their absence.
Shutdown succeeds only with a null result. A failed probe never becomes the
active client, and resolver fallback continues only along the existing order
above. Workspace Trust remains outside and above resolution, so an untrusted
workspace spawns neither this probe nor the active server.
Every terminal path after spawn owns process-tree cleanup, including a direct
child that exits successfully or unsuccessfully before cleanup runs. POSIX
probes lead a dedicated process group. Windows probes run inside a kill-on-close
Job Object whose owner relays raw stdio, so descendants cannot escape merely
because the direct process exits before taskkill /T can address its PID.
This compatibility evidence is activation state, separate from the completed install receipt and its byte-integrity evidence. It does not attest producer provenance or use a private/experimental capability as the standard-LSP baseline.
Downloaded Server Cache
Downloaded servers are stored under the VS Code global storage directory:
servers/
<version>/
<rust-target>/
ripr(.exe)
install-receipt.json
The default server version is the extension version. Users can pin a different
server with ripr.server.version. The configured value must be a canonical
semantic version such as 1.2.3 or 1.2.3-rc.1; path separators, rooted paths,
drive/UNC forms, and . / .. aliases are rejected before URL or filesystem
use.
Each version/target install uses a unique temporary sibling directory and a
per-version/target lock. The extension verifies the manifest version and
archive digest, extracts and probes the staged executable, records its digest
and reported binary version, writes a completed install-receipt.json, and
then atomically renames the validated directory into the final cache path.
Concurrent extension hosts converge on that one completed installation.
A cached executable is eligible only when the receipt has
installationState: "complete", its requested/manifest version, target, and
executable name match the request, and its current executable SHA-256 matches
the receipt. A distribution-bound request additionally requires the receipt's
recorded distribution identity to match the requested server generation, so a
binary verified against a different producer is reinstalled rather than
reused. Binary-only, partial, malformed, or tampered directories are not
probed as cache candidates. A failed install for a new version leaves an
already completed prior version unchanged. Contenders never reclaim an
existing lock based only on age; they fail closed after a bounded wait rather
than risk deleting a replacement owner's lock.
The install receipt establishes local completion and byte integrity. It is not a producer provenance attestation; release provenance verification remains a separate downstream trust boundary.
Manifest
The extension downloads a manifest from GitHub Releases unless
ripr.server.downloadBaseUrl is set:
https://github.com/EffortlessMetrics/ripr/releases/download/v<VERSION>/ripr-server-manifest-v<VERSION>.json
The manifest shape (schema 2, placement-independent) is:
{
"schema_version": "2",
"product_version": "0.11.0",
"distribution_generation": "<sha256 of product/candidate/target-set>",
"source_repository": "EffortlessMetrics/ripr",
"target_set": {
"targets": ["aarch64-apple-darwin", "..."],
"digest": "<sha256 of the configured target set>"
},
"producer": {"tool": "xtask release-server-manifest", "schema": "server-manifest/2"},
"build_identity": {"repository": "...", "candidate_sha": "...", "...": "..."},
"assets": {
"x86_64-pc-windows-msvc": {
"subject": "ripr-server-v0.11.0-x86_64-pc-windows-msvc.zip",
"archive_format": "zip",
"archive_size": 123456,
"sha256": "...",
"executable": {"path": "ripr.exe", "size": 12345, "sha256": "..."},
"receipt": {"path": "...", "sha256": "...", "schema_version": "0.2", "target": "x86_64-pc-windows-msvc"}
}
}
}
The manifest carries relative subject identity only: no scheme, host,
repository, tag, port, query, fragment, or absolute URL may enter manifest
bytes. Retrieval URLs compose later from the accepted installed catalog
placement plus the relative subject. The checksum is for the downloaded
archive. The extension verifies the archive before extraction and admits the
result only after the staged binary's ripr --version probe and
completed-receipt validation pass.
The packaged extension embeds a distribution.json descriptor naming the
server generation and its ordered release placements. Managed resolution
binds the requested version, the cache identity, and the manifest URLs to
that descriptor; a present but unreadable descriptor fails closed instead of
falling back to the legacy version-pinned URL, and an explicit
ripr.server.version bypasses the descriptor as a legacy transport
override.
Previous Public Release Proof
The v0.3.1 GitHub Release verified the default extension server-provisioning
shape:
ripr-0.3.1.vsix
ripr-server-manifest-v0.3.1.json
ripr-server-v0.3.1-x86_64-pc-windows-msvc.zip
ripr-server-v0.3.1-x86_64-unknown-linux-gnu.tar.gz
ripr-server-v0.3.1-aarch64-unknown-linux-gnu.tar.gz
ripr-server-v0.3.1-x86_64-apple-darwin.tar.gz
ripr-server-v0.3.1-aarch64-apple-darwin.tar.gz
checksums.txt
The release/install proof downloaded the Windows server archive, matched its
SHA-256 against the manifest, extracted it, and ran ripr --version,
ripr lsp --version, ripr pilot, and ripr outcome.
For v0.7.0, the release proof must publish the same asset family and extend
the extracted server smoke through ripr agent verify and
ripr agent receipt.
Supported Targets
The first binary release workflow builds these targets:
x86_64-pc-windows-msvc
x86_64-apple-darwin
aarch64-apple-darwin
x86_64-unknown-linux-gnu
aarch64-unknown-linux-gnu
Alpine and musl targets are intentionally separate. If no compatible prebuilt
server exists, users can set ripr.server.path or install ripr manually.
Verification
For local extension smoke before release:
npm --prefix editors/vscode ci
npm --prefix editors/vscode run compile
npm --prefix editors/vscode run package
npm --prefix editors/vscode run test:e2e
The e2e suite runs in a fixture Rust workspace and covers extension activation,
defaults-first draft mode, command registration, LSP-first seam context
collection with CLI fallback, targeted-test brief copying, suggested assertion
copying, related-test opening, malformed command arguments, and restart
behavior. The v0.7.0 release proof verifies the server archive path and local
VSIX package path for current provisioning. Defaults-first public install proof
for ripr pilot, ripr outcome, ripr agent verify, and
ripr agent receipt is covered by
Installation verification.
Future Bundled VSIXs
The universal VSIX plus downloader is the first one-click path. Platform-specific VSIXs can come later:
win32-x64
linux-x64
linux-arm64
darwin-x64
darwin-arm64
When those exist, bundled binaries should remain ahead of downloaded binaries in the resolution order, with auto-download retained as fallback/update machinery.