# Runrail Desktop 2.4 and Local Audit Runner

Runrail Desktop reviews a clean local Git repository through the same bounded
Runrail Local and Ra v1 workflow. Repository content remains on the operator
machine. The app exports a local proposal patch and review evidence, but it
never applies the patch automatically.

Release 2.1 completes the Starter correction loop. A server-owned review can be
reopened exactly from local history, its checksum-bound patch can be inspected
in browser memory, and saving current hunk attention recomputes Agent Assurance
without another Git review. Starter rerun does not depend on Pro-only Recheck;
Pro continuity remains optional enrichment. Diff content is never written to
browser storage or portable evidence.

## Subscription Entitlement

Runrail 2.1 keeps the browser-authorized device-key flow introduced in 1.7.
First write a signed public enrollment request:

```bash
runrail license request \
  --output /absolute/path/to/runrail-device-enrollment-request.json \
  --json
```

Select that public JSON file in the Veyact subscriber console. It contains the
device public key, its SHA-256 digest, a random installation fingerprint, a
client nonce, and a proof-of-possession signature. It contains no private key.
The console returns a short-lived, one-time ticket bound to that exact public
key and installation fingerprint. Complete enrollment with the downloaded
ticket:

```bash
runrail license enroll \
  --ticket /absolute/path/to/runrail-device-enrollment-ticket.json \
  --json
```

Runrail reuses the pending local Ed25519 private key at completion and rejects a
ticket bound to another key or installation before network access. A verified
activation is stored automatically; no lease-path, public-key-path, device-ID,
or entitlement-required environment variable assembly is needed. Successful
completion removes the pending key record and consumed ticket where the local
filesystem permits. The managed activation never stores the ticket secret, and
license command output never prints that secret, a private key, or a raw lease.

Inspect or explicitly renew the enrolled device with:

```bash
runrail license --json
runrail license renew --json
```

Status reports `valid`, `renewal-needed`, `offline-grace`, or `expired` without
printing a key or raw lease. Signed lease-v2 binds the device public-key digest,
monotonic lease sequence, canonical plan features, renewal time, normal expiry,
48-hour maximum grace deadline, subscription-only authority, and explicit
absence of execution authority. An enrolled Starter device supports candidate
review, source-free Agent Assurance, and checksum-only passports but not the
Pro Revision Workspace, revision comparison, Evidence Continuity, Repository
Trust Profiles, weekly reports, Candidate Tournament, ProofGraph, or
device-signed passports.

An enrolled Pro device can derive a local Repository Trust Profile and rolling
weekly engineering report from verified local review history. The profile is
local metadata and may contain a preferred base plus a salted fingerprint
scoped to that history root. The weekly report removes repository identity,
paths, branches, commits, source, diffs, and raw verifier output. Both remain
telemetry-free and cannot change the base-owned review contract. Pro may also
export a separate device-signed Change Passport. It proves possession of that
enrolled device key only; it does not prove organizational identity,
compliance, code correctness, or merge approval.

Pro also adds two local deterministic decision aids:

- **Candidate Tournament** reviews two to five existing candidate branches
  against the same confirmed base, base-owned contract, and `safe-static`
  verifier, then ranks human review order from visible risk, contract,
  coverage, and evidence metrics. It never selects or claims to identify the
  best code.
- **ProofGraph** links verified local revisions, contract rules, evidence,
  findings, exact-hunk attention, and append-only dispositions. Every finding
  remains visible; a disposition never silently suppresses evidence or changes
  policy.

Both artifacts are path-free and checksum-linked. They add no project-test
execution, source mutation, arbitrary shell, network call, merge approval, or
model authority.

At the start of a value-bearing command, Runrail makes no entitlement request
before the signed `renewAfter`. At or after that time it may make one short,
device-signed request to the Veyact entitlement endpoint containing only
`deviceId`, `leaseSequence`, a fresh nonce, and the signature. It never adds a
repository, path, task, diff, command, source, prompt, model input, or provider
field. If that request fails, Runrail continues under the existing signed
normal or grace window and emits a bounded warning. Value-bearing use fails
only after signed grace ends and renewal cannot recover. There is no daemon,
timer, automatic background task, or retry loop; `license renew` remains the
explicit operator action.

`doctor`, `license`, `license request`, and `license enroll` work before an
entitlement exists. The public preview also permits `sample`, `readiness`, and
`desktop`, including `desktop --repo`, so a prospective user can complete the
disposable guided sample and inspect read-only repository readiness before
enrollment. The CLI form is:

```bash
cd /path/to/repository
runrail desktop --repo .

# Or print the same read-only readiness result in the terminal.
runrail readiness --repo . --base main --json
```

The literal `.` shorthand is resolved once by the local CLI. The Desktop server
and loopback API continue to require a normalized absolute Git worktree path;
other relative paths are refused.

Preview inspection reports only local Git, stack, contract, base, and candidate
metadata, then derives one readiness state, five bounded checks, and a
Review-Ready Brief with one objective and one done condition. The portable
brief excludes repository paths, branch names, commits, source, and diffs. It
creates no repository fingerprint, loads no history, persists no readiness
artifact, uses no network, runs no project test, and cannot start a candidate
review. `prepare`, `audit`, `review`, `focus`, `coverage`, `handoff`,
`assure`, `recheck`, `compare`, `lineage`, agent launch, and advisory commands
remain feature-gated. The preview sample still uses a Runrail-owned disposable
Git fixture. Only an explicitly marked Runrail 1.3.0 distribution retains
legacy package compatibility.
Tampered, wrong-device, stale-catalog, expanded-feature, symlinked, non-regular,
oversized, unknown-key, replayed, and out-of-window state fails closed.

Managed entitlement files use private file modes where the operating system
supports them and are stored under:

- Windows: `%LOCALAPPDATA%\Runrail\entitlement`
- macOS: `~/Library/Application Support/Runrail/entitlement`
- Linux/WSL2: `${XDG_DATA_HOME:-~/.local/share}/runrail/entitlement`

The active bundle is replaced atomically. A verified
`device-entitlement.previous.json` is preserved for interrupted-replacement
recovery; an existing tampered active bundle is never hidden by fallback.
Entitlement origins require HTTPS. Literal HTTP loopback is accepted only by
the explicit test-only `RUNRAIL_ALLOW_INSECURE_LOOPBACK_TEST=1` client setting.

## Requirements

- Windows, macOS, Linux, or WSL2
- Node.js 20 or newer
- Python 3.11 or newer
- Python `venv` support
- Git

Repository review, evidence generation, and deterministic recommendations stay
local and require no external model provider. Enrollment and explicit renewal
contact Veyact. A value-bearing command may occasionally renew the bounded
device entitlement metadata described above after signed `renewAfter`;
repository content and model input never leave the machine through that path.

## Fast preview start

After verifying and extracting the downloaded archive, use the fixed launcher
for the shortest first run:

- Windows: open `START-RUNRAIL-PREVIEW.cmd`
- macOS: open `Start Runrail Preview.command`
- Linux or WSL2: run `./start-runrail-preview.sh`

The launcher accepts no repository, command, argument, environment, or provider
input. It runs the checksum-bound installer, verifies the installed package with
`doctor`, completes the disposable local sample, and opens Runrail Desktop. The
sample requires no account and never uploads a repository, applies source,
executes project tests, or grants an AI provider authority. Real-repository
review remains entitlement-gated. The manual installation commands below remain
available for operators who want to inspect every step.

## Install on Windows

Run these commands in PowerShell:

```powershell
$expected = (Get-Content .\runrail-desktop-v1.zip.sha256).Split()[0].ToLower()
$actual = (Get-FileHash .\runrail-desktop-v1.zip -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $expected) { throw "Runrail archive checksum mismatch" }
Expand-Archive .\runrail-desktop-v1.zip .
Set-Location .\runrail-local-v1
$installation = node .\install.mjs | ConvertFrom-Json
$runrail = Join-Path $installation.binDir "runrail.cmd"
& $runrail doctor --json
& $runrail sample --json
& $runrail desktop
# Enrollment is required only before reviewing a real repository:
& $runrail license request --output "$env:USERPROFILE\Downloads\runrail-device-enrollment-request.json" --json
# Select the request in the subscriber console, then use its downloaded ticket:
& $runrail license enroll --ticket "$env:USERPROFILE\Downloads\runrail-device-enrollment-ticket.json" --json
```

The checksum command fails before extraction when the values differ. Invoking
the shared Node installer avoids a first-use PowerShell script execution-policy
dependency; the packaged `install.ps1` wrapper remains available for managed
environments. The installer returns its resolved `binDir` and shell-ready
`nextCommands`; the commands above use that emitted directory, so they also
work with a custom install base or bin directory and do not require `PATH`.
The default Windows install writes `runrail.cmd` and `runrail.ps1` under
`%LOCALAPPDATA%\Runrail\bin`. It also adds **Runrail Desktop** to the Windows
Start Menu and writes `runrail-desktop.cmd` / `runrail-desktop.ps1` for
terminal launch.

## Install on macOS

```bash
shasum -a 256 -c runrail-desktop-v1.zip.sha256
unzip runrail-desktop-v1.zip
cd runrail-local-v1
installation_json="$(./install.sh)"
printf '%s\n' "$installation_json"
runrail_bin="$(printf '%s' "$installation_json" | node -e 'const fs = require("node:fs"); process.stdout.write(JSON.parse(fs.readFileSync(0, "utf8")).binDir)')"
"$runrail_bin/runrail" doctor --json
"$runrail_bin/runrail" sample --json
"$runrail_bin/runrail" desktop
# Enrollment is required only before reviewing a real repository:
"$runrail_bin/runrail" license request --output "$HOME/Downloads/runrail-device-enrollment-request.json" --json
# Select the request in the subscriber console, then use its downloaded ticket:
"$runrail_bin/runrail" license enroll --ticket "$HOME/Downloads/runrail-device-enrollment-ticket.json" --json
```

The checksum command fails before extraction when the values differ. The
installer emits its resolved `binDir` plus shell-ready `nextCommands`; the
commands above invoke the emitted full path even when the launcher directory
is not on `PATH`. The installer also adds **Runrail Desktop** to
`~/Applications` and installs the `runrail-desktop` terminal command.

## Install on Linux or WSL2

```bash
sha256sum -c runrail-local-v1.tar.gz.sha256
tar -xzf runrail-local-v1.tar.gz
cd runrail-local-v1
installation_json="$(./install.sh)"
printf '%s\n' "$installation_json"
runrail_bin="$(printf '%s' "$installation_json" | node -e 'const fs = require("node:fs"); process.stdout.write(JSON.parse(fs.readFileSync(0, "utf8")).binDir)')"
"$runrail_bin/runrail" doctor --json
"$runrail_bin/runrail" sample --json
"$runrail_bin/runrail" desktop
# Enrollment is required only before reviewing a real repository:
"$runrail_bin/runrail" license request --output "$HOME/runrail-device-enrollment-request.json" --json
# Select the request in the subscriber console, then use its downloaded ticket:
"$runrail_bin/runrail" license enroll --ticket "$HOME/runrail-device-enrollment-ticket.json" --json
```

The installer adds **Runrail Desktop** to the Linux desktop application menu.
WSL2 installs the CLI and launches the desktop through the Windows host
browser. If host-browser launch is unavailable, `runrail desktop` prints the
private token-bearing loopback URL so it can be opened manually on the same
machine. The installer emits its resolved `binDir` and shell-ready
`nextCommands`; the commands above use the emitted full path and therefore do
not assume the launcher directory is already on `PATH`.

Generated command and desktop launchers prefer the Node executable verified
during installation. If a later Node upgrade removes that exact executable,
they resolve the current `node` application from `PATH`; the CLI then refuses
versions older than Node 20 with a stable no-authority error.

The installer and `runrail doctor` verify the complete package manifest, Python
runtime, installation state, command launchers, and native desktop entry before
reporting success. Reinstalling the same v1 release uses a staged replacement;
if the post-install lifecycle check fails, the prior verified release is
restored.

The v1 archive is checksum and manifest verified. Its Windows shortcut, macOS
application bundle, and Linux desktop entry are generated locally during
installation; they are not yet backed by a vendor code-signing certificate or
Apple notarization. Review the published checksum before installation and
expect the operating system to request confirmation where its local policy
requires it. A same-origin SHA-256 file proves transfer integrity against the
published bytes; it does not independently prove publisher identity.

## Uninstall

Run the shared Node uninstaller from the same checksum-verified extracted
package used for installation:

```bash
node ./uninstall.mjs
```

Keep any custom `RUNRAIL_INSTALL_BASE`, `RUNRAIL_BIN_DIR`, and
`RUNRAIL_DESKTOP_ENTRY_DIR` values identical to the install command. If the
process or machine stops during removal, rerun the exact command. The
checksum-bound uninstall journal resumes only verified Runrail-owned
components and refuses changed, redirected, symlinked, or conflicting paths
with a JSON error. The install-base workspace, configured `RUNRAIL_HOME`, and
local audit evidence are preserved.

## Use

The examples below use `runrail` for brevity. If the installer reported that
its bin directory is not on `PATH`, keep using the full launcher path derived
from its emitted `binDir`, or run the exact full-path command shown under
`nextCommands`.

```bash
runrail license --json
runrail license renew --json
runrail desktop
runrail doctor --json
runrail sample --json
runrail prepare --repo /absolute/path/to/clean-repository --json
runrail audit \
  --request /path/to/subscriber-request.json \
  --repo /path/returned/by/prepare \
  --task "repair reviewed service status" \
  --json

# Or audit an existing AI-generated candidate branch against its base.
runrail review \
  --repo /absolute/path/to/clean-repository \
  --base main \
  --candidate ai/candidate-change \
  --verifier safe-static \
  --json

# Rebuild or verify the path-free ordered plan for that audit.
runrail focus \
  --audit /absolute/path/to/the/runrail/review/audit.json \
  --json
```

`runrail desktop` starts a per-session HTTP server bound only to
`127.0.0.1`, opens the local workbench, and stops when the operator chooses
Stop or ends the process. The desktop API requires a random session token and
same-origin requests. It accepts only the fixed candidate review, Review
Coverage, Revision Workspace, and advisory operations. It has no repository
upload, arbitrary shell, project-test, automatic source-apply, merge, or
provider-key storage path. Provider variables are removed from ordinary desktop
child processes and are available only to an explicit DeepSeek advisory
request with network consent.

Use **Run guided sample** in the desktop app, or `runrail sample --json`, for a
first review without choosing a repository. Runrail creates a disposable Git
fixture inside its own local workspace and sends it through the same candidate
review path. The result is real local evidence, not a video or replay. It still
does not run project tests, upload a repository, or apply a source change.
Runrail retains at most the three newest Runrail-owned guided fixtures and
never prunes unmarked operator content.

Candidate review writes six primary files plus path-free Review Focus and
Review Coverage directories under the returned local review directory:

- `candidate.patch`: the proposed Git diff.
- `audit.json`: checksum-identified policy, verifier, boundary, and decision evidence.
- `REVIEW.md`: the human checklist and deterministic findings.
- `ROLLBACK.md`: the no-source-mutation recovery note.
- `review.html`: a self-contained, script-free local decision view.
- `REVIEW_PASSPORT.json`: a path-free, checksum-linked evidence handoff.
- `focus/focus.json`: the checksum-linked ordered review plan.
- `focus/REVIEW_FOCUS.md`: the reduced human checklist.
- `focus/focus.html`: a self-contained, script-free focus view.
- `coverage/<coverage-id>/coverage.json`: exact-hunk human-attention state.
- `coverage/<coverage-id>/REVIEW_COVERAGE.md`: the reduced attention handoff.
- `coverage/<coverage-id>/coverage.html`: a self-contained, script-free
  coverage view.

The deterministic `runrail-review-policy-v1` profile classifies security,
dependency, delivery, migration, missing-test, change-size, Python, test, and
documentation signals. Its risk level is review prioritization, not merge
approval: every result records human approval required, project tests required,
and merge ready false.

## Base-owned review contract

Runrail 1.7 optionally reads `.runrail/review-contract.json` from the selected
base commit. The candidate branch cannot replace, relax, or bypass that policy.
The strict v1 contract can lower the built-in changed-file and diff-line
budgets, map path prefixes to required review lanes and evidence, and require
companion path groups. Invalid contracts, missing companion evidence, budget
violations, and candidate changes to the contract fail the preflight.

When the base has no contract file, Runrail uses its built-in contract and
still derives required review evidence from the changed paths. The audit stores
the normalized contract fingerprint, its source, matched rules, missing
companions, required lanes, and required evidence.

The default `safe-static` verifier performs only:

- isolated Python standard-library compilation without importing project code;
- `node --check` for tracked `.js`, `.mjs`, and `.cjs` files;
- strict JSON parsing for tracked `.json` files.

It does not run package scripts, tests, build tools, application code, or
arbitrary commands. Changed TypeScript, JSX, TSX, and other unsupported source
types block the static preflight because Runrail did not parse them; the audit
still records the bounded unsupported-file count for manual follow-up. The legacy
`--verifier python-compile` profile remains available for compatible Python
workflows.

`REVIEW_PASSPORT.json` binds the audit checksum, base/candidate relationship,
contract fingerprint, static-check summary, required evidence, decision
boundary, and source-unchanged proof into a path-free file with its own content
checksum. It detects content changes; it is not a signature, certificate, or
proof of who created the evidence.

## Review Focus

Every candidate review now derives a deterministic Review Focus plan. It puts
blocked preflight repair, base-owned contract evidence, specialist review,
approved project checks, manual patch inspection, and the final human decision
in one canonical order. Unlike the optional advisory, Review Focus also works
when the preflight is blocked.

`runrail focus --audit <absolute-audit.json> --json` verifies the owned audit
and either creates or revalidates the three files under `focus/`. The JSON,
Markdown, and HTML are path-free and contain no source, diff, file path,
repository identity, commit, task, raw output, author identity, command, or
provider response. The source checksum can correlate copies of the same audit;
it does not authenticate origin. Review Focus does not open a repository, use
a network, execute project tests, mutate source, approve a merge, or grant
authority.

## Review Coverage

Every candidate review creates an initial path-free Review Coverage artifact
with each textual diff hunk marked `unreviewed`. In Runrail Desktop, set an
individual hunk to `reviewed`, `needs-revision`, or `unreviewed`, then choose
**Save attention snapshot**. The UI exposes an opaque hunk number and bounded
line counts; it does not place source paths or diff text in the coverage
artifact.

The equivalent CLI command verifies or creates coverage for one Runrail-owned
audit:

```bash
runrail coverage \
  --audit /absolute/path/to/review/audit.json \
  --json
```

An attention manifest created from the current coverage can be applied with
`--attention /absolute/path/to/attention.json`. To carry reviewed attention
into a related revision, also pass the prior immutable
`coverage.json` through `--previous`. Carry-forward is deliberately strict:
the prior and current reviews must have a bound same-base or linear-successor
relationship, and the exact file scope, hunk header, context, and changed bytes
must occur exactly once in each artifact. Changed, shifted, split, duplicated,
ambiguous, or new hunks reset to `unreviewed`.

Coverage records human attention, not correctness, approval, or merge
readiness. It does not authenticate origin, open a repository, run project
tests, call a model, mutate source, apply a patch, or grant authority.

## Agent Assurance

After a review, Runrail can turn its high- and medium-severity findings into a
source-free correction brief for any coding agent:

```bash
runrail handoff \
  --audit /absolute/path/to/prior/review/audit.json \
  --json
```

The packet contains fixed Runrail finding IDs, product-authored objectives,
audit and contract checksums, acceptance rules, and explicit no-authority
boundaries. It excludes repository identity, source, diffs, paths, refs,
commits, task text, raw verifier output, provider keys, and model output. The
Desktop derives recurrence history only from verified parent review sessions;
the CLI handoff does not accept caller-provided history.

After the coding agent creates a new candidate revision, review it normally and
verify the correction loop:

```bash
runrail assure \
  --packet /absolute/path/to/agent-assurance/packet.json \
  --before /absolute/path/to/prior/review/audit.json \
  --after /absolute/path/to/current/review/audit.json \
  --coverage /absolute/path/to/current/coverage.json \
  --json
```

The result classifies findings as `resolved`, `remaining`, `new`, or
`reintroduced`. `ready-for-human-decision` requires a related checksum-verified
audit, the same base-owned review-contract fingerprint, passing preflight and
contract evidence, no remaining or new high/medium finding, and verified
current Review Coverage with no unreviewed or needs-revision hunk. Without
current coverage, the CLI conservatively reports `needs-correction`.

Agent Assurance does not run a coding agent, execute project tests, call a
model, open a network connection, change policy, apply a patch, mutate source,
determine correctness, or approve a merge. Its JSON and Markdown artifacts are
stored privately under the owning review's `agent-assurance/` directory.

## Desktop Revision Workspace

Runrail Pro and higher plans add **Recheck** to the Desktop workflow. After a
current review, provide the absolute path to one prior Runrail `audit.json` and
the immutable `coverage.json` saved for that exact prior audit. The Desktop
invokes the same entitlement-gated CLI path:

```bash
runrail recheck \
  --before /absolute/path/to/prior/review/audit.json \
  --after /absolute/path/to/current/review/audit.json \
  --previous /absolute/path/to/prior/review/coverage/COV-.../coverage.json \
  --json
```

Recheck verifies both schema-v4 audits, their declared revision relationship,
their base-owned review-contract fingerprints, the prior coverage checksum,
and the current patch checksum. It writes a deterministic Re-review Map plus
newly carried Review Coverage beneath the current review:

- `deltas/<delta-id>/delta.json`: path-free policy, finding, and attention
  deltas with a fixed ordered next-action list.
- `deltas/<delta-id>/REVIEW_DELTA.md`: the reduced human re-review handoff.
- `deltas/<delta-id>/delta.html`: a self-contained, script-free local view.
- `coverage/<coverage-id>/...`: the current exact-hunk attention snapshot.

Only an exact file scope, hunk header, context, and changed-byte sequence that
occurs uniquely in both revisions may retain a non-unreviewed attention state.
The map calls every other current hunk **current attention required**. It does
not pretend to know whether a hunk is new, semantically changed, or merely
previously unreviewed when the evidence cannot prove that distinction.

The Re-review Map is evidence, not approval. It does not authenticate origin,
open a repository, run project tests, determine semantic correctness, perform
a security review, call a model, mutate source, apply a patch, or approve a
merge.

## Compare a revised candidate

After reviewing a second candidate revision, compare both verified audit files:

```bash
runrail compare \
  --before /absolute/path/to/baseline/review/audit.json \
  --after /absolute/path/to/revised/review/audit.json \
  --json
```

The audits must declare the same base commit or a linear relationship where the
revised audit starts from the baseline candidate commit. Two same-base audits
are alternate candidates, not a chronological successor. Runrail verifies both
embedded content checksums, deterministic policies, and contract fingerprints
before writing:

- `comparison.json`: machine-readable review-priority, finding, and file deltas.
- `REVIEW_COMPARISON.md`: a reduced human handoff.
- `comparison.html`: a self-contained, script-free local revision view.

Review priority describes deterministic triage evidence, not code quality.
Runrail does not claim that priority decreased when the two audits use different
contract bases; it reports that the policy basis changed.
Comparison does not authenticate either audit's creator, open a repository,
run project tests, determine semantic correctness, perform a security review,
apply source changes, or approve a merge.

## Build Evidence Continuity

Pro and higher plans can connect 2 to 20 related Runrail review audits into one
declared evidence sequence:

```bash
runrail lineage \
  --audit /absolute/path/to/first/review/audit.json \
  --audit /absolute/path/to/second/review/audit.json \
  --audit /absolute/path/to/latest/review/audit.json \
  --json
```

Runrail verifies every audit and adjacent relationship before writing
`lineage.json`, `REVIEW_LINEAGE.md`, and script-free `lineage.html` beneath the
latest review. The path-free artifact records contract-basis continuity,
review-priority direction, finding absence and recurrence, and a SHA-256
content-integrity chain.

The order is declared by the operator. The chain detects internal content
changes, but it does not authenticate creator, time, historical order, or
append-only storage. A changed contract basis suppresses a decreased-priority
claim. Human approval and external project checks remain required.

## Candidate Tournament and ProofGraph

Runrail Desktop Pro can compare two to five existing candidate branches against
one confirmed base through **Candidate Tournament**. Each candidate goes
through the same base-owned review contract and `safe-static` verifier before
Runrail orders the human review queue using visible risk, contract, coverage,
and evidence metrics. Input order does not affect the result. The highest
ranked candidate is the one to inspect first, not a claim that it is the best
code, merge-ready, correct, or secure.

After local review sessions exist, **ProofGraph** connects their verified
revisions, contract rules, required evidence, finding occurrences, exact-hunk
attention, and append-only dispositions. Every finding remains visible.
`not-relevant` and `accepted-exception` are explicit operator records, not
hidden suppression or learned policy.

Both features are available through the token-protected loopback Desktop only.
Their JSON artifacts are path-free and checksum-linked and exclude repository
identity, local paths, branch names, commits, source, diffs, raw verifier
output, exception reason, and exception owner. They open no public execution
API, run no project tests, call no model or network, mutate no source, apply no
patch, and approve no merge.

## Offline candidate recommendation

Every installation includes a deterministic, provider-free recommendation:

```bash
runrail recommend \
  --audit /absolute/path/to/the/runrail/review/audit.json \
  --json
```

This command uses the same checksum-verified local policy as the audit. It
requires no model, key, account, or network connection, transmits no fields,
and writes a provider-neutral `candidate-advisory.json` with authority `none`.

## Optional DeepSeek candidate advisory

After a passing `runrail review`, an operator can explicitly request a
metadata-only candidate advisory:

```bash
export RUNRAIL_DEEPSEEK_ADVISORY_ENABLED=true
export RUNRAIL_DEEPSEEK_ADVISORY_API_KEY='your-own-provider-key'
runrail recommend \
  --audit /absolute/path/to/the/runrail/review/audit.json \
  --provider deepseek \
  --allow-network \
  --json
```

`runrail advise` remains a compatibility alias for the same DeepSeek path.
The DeepSeek receipt is written separately as
`candidate-advisory-deepseek.json`, so the offline and optional provider
advisories can coexist for the same audit without overwriting each other.
This separate command sends only bucketed counts and booleans derived from a
passing preflight whose embedded content checksum matches and whose deterministic
policy recomputes. The checksum does not authenticate the file's creator. The
command does not transmit source, diff content,
file paths or names, commits, repository identity, task text, raw verifier
output, or the audit run id. The response may select only fixed local candidate
IDs or `ABSTAIN`; it cannot create commands, patches, verifier choices, answers,
or apply actions. Its recorded authority is `none`, and a human remains
responsible for every next step. The provider key stays in the operator
environment and is never written to a Runrail artifact.

The sellable v1 capability is a base-commit-owned candidate review contract,
bounded non-executing Python/JavaScript/JSON preflight, portable evidence
passport, exact-hunk Review Coverage, deterministic Re-review Maps, and local
revision comparison.
Runrail materializes Git blobs without checkout filters or repository code,
disables source-repository hook and filesystem-monitor execution paths, scans
the complete candidate tree and diff, verifies each materialized blob against
its Git object identity, and performs only the fixed syntax/parse checks
described above.

The two bundled repair request classes are deterministic learning fixtures for
the audit workflow; they are not general code-repair capabilities. Runrail does
not run project tests, determine semantic correctness, perform a complete
security review, authenticate evidence origin, or provide an operating-system
sandbox. It requires a trusted local operator machine. It refuses dirty
repositories, replacement refs, local Git content filters, symlinks, unsafe
paths, secret-like additions, binary changes, gitlinks, arbitrary commands,
network bridges, and automatic source apply. Inspect every local patch and run
your own project tests before merging or applying it.
