Skip to content

Latest commit

 

History

History
946 lines (764 loc) · 48.2 KB

File metadata and controls

946 lines (764 loc) · 48.2 KB

Command-line guide

rbit keeps project intent, local machine configuration, building, and verification separate. Commands write plain text by default, and long work uses one live progress line in an interactive terminal. Pass --format ndjson (before or after the subcommand) when CI or another program needs stable machine-readable events; see Machine-readable output. Pass --quiet (before or after the subcommand) to silence text-mode progress: phase starts, heartbeats, completion lines, unit counts, and the interactive progress display. Results, warnings, errors, and the context line written when a phase fails still print. --quiet does not change ndjson output, because machine readers rely on receiving every event. Interactive terminals and saved logs use the same plain-language phase names. Exact internal step IDs remain available in failure details, rebuild explanations, and ndjson. Output is plain by design: no colour, no shell completion, and no terminal control beyond the transient progress line.

Printed follow-up commands use POSIX shell quoting on macOS and Linux, and PowerShell quoting on Windows. Machine events also carry the unquoted argv array for callers that launch a process directly.

This page has one section per command, in the order rbit --help lists them. It explains what commands do and how they fit together. The exact flags and defaults are generated from the parser into cli-reference.md. Getting started owns the narrative walk from a bare CMake project to a verified build, while the focused workflow guides own discovery, CMake import, and CI behavior.

For an existing project, the everyday path is short:

rbit status .
rbit build .
rbit verify . --report-dir build/reprobit-report

status names the next missing setup item. build is the fast incremental developer loop; verify always starts fresh and writes the trust report. After editing a file that already belongs to the project—including a shared header used by many source files—use rbit repair .. Run setup once on each machine to prepare and remember its local compiler.

Every command that takes a project accepts it as a positional argument, such as rbit status ..

Advanced: progress events

Redirected logs and CI receive phase starts, heartbeats, completed units, and a final event, so a compiler or verifier never goes silently idle. Producer work and overall workflow progress use separate event types. Discovery compiler totals include declaration experiments only for the source files selected by the committed overlay graph. In text mode, --quiet drops this whole channel (a heartbeat exists to prove liveness, which is exactly what --quiet opts out of) and keeps only the failure context line; in ndjson mode the events are always streamed.

rbit init

Start a ReproBit project. Name the real CMake target when initializing and repeat --target for projects that produce more than one binary:

rbit init . --target program

init creates the project entry point, adds root ignore entries for ReproBit's local state, and creates an empty, explicitly incomplete source record, so a new project cannot appear build-ready before its real files are reviewed. The default rebuilt-output and reference filenames follow each target name. For target-specific custom paths, repeat --artifact TARGET=PATH or --oracle TARGET=PATH; for a single target the TARGET= prefix is optional:

rbit init . --target program --artifact build/app.exe --oracle reference/program.exe

The --logical-source, --logical-build, and --logical-toolchain DOS paths are the compiler-visible roots recorded in reprobit.toml (defaults R:\source, R:\build, R:\toolchain); see platforms before changing them.

rbit setup

Prepare the compiler and this machine for a project:

rbit setup .
# Or use an existing installation:
rbit setup . --toolchain-root /opt/toolchains/msvc42

setup selects or downloads the compiler, authenticates it, creates the project lock when absent, verifies an existing lock, and probes the host backend. It remembers the local compiler path only after those checks pass, so a failed attempt preserves the previous default. That is the normal workflow on macOS, Linux, and Windows. It ends with the same checklist status prints, so a finished machine setup and a still-incomplete project are reported together. Machine setup and project setup are separate: rbit setup can finish installing and checking the compiler while rbit status still lists missing project files. Exit status 1 means a backend check failed.

rbit doctor

doctor is the read-only diagnostic underneath setup. It checks the selected host backend and the compiler chosen for the project against its saved lock. That is the path passed on the command line, set in the environment, remembered by setup, or found in the standard location:

rbit doctor .
rbit doctor . --toolchain-root /opt/toolchains/msvc42

Add --execute-probe to execute the bounded Wine probe on POSIX. On native Windows the opt-in probe creates a fresh, verified logon session and defines a temporary drive only in that session. The real producer starts suspended inside a nested Job Object, and the probe requires its descendant to observe the same drive. The mapping is removed only after that complete producer tree exits. Without a project, --toolchain-root also needs --profile.

rbit toolchain provision

Download and authenticate a supported compiler outside any project:

rbit toolchain provision msvc_4_2

Automatic acquisition is currently available only for Microsoft Visual C++ 4.2. The installation goes to this platform's standard user location unless --destination says otherwise, and its path is remembered unless --no-save is given. rbit setup runs the same provisioning automatically when a project needs it, so this command is mainly for machines prepared before any project exists (the advanced declaration-discovery example uses it).

rbit toolchain lock

Record the exact compiler files this project expects. setup creates the lock automatically; the lower-level command remains available for CI images and unusual manual installations that need explicit runtime files:

rbit toolchain lock . --toolchain-root /opt/toolchains/msvc42 \
  --runtime-file wine/x86/cl \
  --runtime-file wine/x86/rc \
  --runtime-file wine/x86/link \
  --runtime-file wine/x86/lib \
  --runtime-file wine/x86/wine-msvc.sh

An existing project always writes the compiler lock path declared in reprobit.toml; --output is only for bootstrapping a directory that has no project configuration yet.

The lock command hashes required compiler producers and portable include and library tree receipts. It also writes profile_sources, the selected profile's reviewed immutable repository inputs for each profile-owned installed path. Those inputs neither prove how local bytes were acquired nor replace the exact file and tree receipts. The authenticated provisioner and CI workflow establish acquisition; the lock receipts establish the installed content. Platform wrappers or support files that participate in execution must be named explicitly with repeatable --runtime-file arguments and remain outside profile_sources. The five paths above are the complete portable runtime set for MSVC 4.2 on POSIX. wine/x86/msvcenv.sh is used only while CMake configures an import or refresh tree; direct ReproBit builds do not execute it, so the provisioner authenticates it but the portable runtime lock does not include it. Committed lock paths are relative to the supplied toolchain root; the physical root itself remains local configuration. rbit validate rejects a registered profile whose locked profile paths are missing, disagree with these reviewed repository inputs, or assign an extra profile source to a wrapper path.

rbit source preview

Show source changes and records that need review without writing:

rbit source preview .

source preview hashes the proposed Git-tracked read set without writing. Repeat --path to provide an explicit complete file or tree set instead. It is not a filter over the current record: every omitted path is reported as a removal. Without --path, preview uses the selection saved by the last lock when the manifest has one and every Git-tracked file otherwise; the selection line and event field say which. Text output keeps long change lists brief; NDJSON retains every path.

To add a new file to the reviewed source list—or remove a locked one—preview the new list first. repair keeps using the exact locked list and never silently admits another Git-tracked file. Before the first import, preview prints the exact source lock command. Once CMake records exist, it normally prints rbit import cmake . --refresh, carrying forward every explicit --path selection and the saved CMake import options. If an older graph does not contain those options, preview refuses to guess and asks for one ordinary CMake re-import first.

rbit source export

Write the reviewed effective source view used by compilers and analysis tools:

rbit source export . --destination build/reprobit-debug/source

Source-aware tools must read the same reviewed source view as the compiler. This matters when an intervention adds declarations or otherwise moves source lines. The export contains project inputs admitted by the source lock, with the reviewed source adjustments applied, plus one hidden ownership marker. It does not contain reference binaries, compiler files, build outputs, or private run state. Running the command again safely replaces the prior export, including files that are no longer part of the reviewed source view. ReproBit marks directories it creates and refreshes only those marked exports, so it cannot replace an unrelated directory by mistake. The destination also cannot overlap source inputs, project records, reference binaries, or build outputs. Point the tool's source root at the exported directory.

rbit source lock

Safely record tracked or explicitly named source inputs:

rbit source lock .

source lock publishes the set shown by source preview after review. A successful lock prints the next required step—usually placing the original binary, running the first rbit import cmake ., or checking rbit status .. After a CMake import exists, use the refresh command printed by preview rather than locking a changed file list separately.

Repeat --path to admit only the named files or trees. In a Git worktree the selection admits the tracked files under each root, untracked files stay invisible, and a root without tracked files is an error. The lock saves those roots as selection in the source manifest, so later source preview and source lock runs without --path reuse the same roots instead of re-admitting every tracked file. Name a new --path set to replace the saved selection.

Advanced: source-lock safety and generated project records

source lock publishes the manifest and, when one exists, its build-plan binding in one guarded transaction. Every admitted source file is checked again, so an edit racing the lock aborts rather than saving mixed state. It does not rewrite translation-unit, intervention, or proof checks. If those checks became stale after a routine edit, use rbit repair .. The advanced source regenerate command lets you inspect only the mechanical changes when diagnosing a repair.

rbit source regenerate

Advanced maintenance tool. After editing an existing project file, normally run rbit repair . instead. source regenerate is the preview used inside the maintenance flow; it is useful when you want to inspect mechanical record updates without building or verifying:

rbit source regenerate .          # preview only
rbit source regenerate . --apply  # apply only these mechanical changes

It re-renders stale records against the current bytes and can propose changes for four record families. Staleness is decided by rendering, not by the clean digest alone: an output whose clean bytes are unchanged but whose reviewed operations were edited (a retuned declaration-run count, a dropped declaration) is re-rendered and its effective digest re-derived, and every private donor rendering is rendered again so a change in the owning unit's canonical operations reaches the donor's pins too.

  • Source-adjustment outputs — the clean source and newly rendered output.
  • Private donor renderings — source prepared for one owning translation unit, including its reviewed adjustments.
  • Declaration donors — their rendered source and the checked insertion points around a declaration.
  • Translation-unit source checks — in both per-unit records and the build plan.

The human preview says what would change, prints a concise count and per-document summary, and writes nothing. With --format ndjson, the event's changes field contains each field-level before/after value for tooling. --apply reports what it saved and writes all changed documents in one guarded transaction that also checks the exact source bytes read by the plan, so a concurrent edit aborts instead of committing mixed state. It then points back to rbit repair . for the build and exact check.

The command fails closed when it cannot re-derive a check. It only proposes or applies mechanical record changes: it does not lock, build, verify, or certify the project. It remains a separate command because this read-only preview is useful for diagnosis; repair already runs the same planner automatically, then handles compiler-dependent fallout and exact verification. Prefer rbit repair . unless you specifically need the intermediate view.

rbit import cmake

Prepare and record an ordinary CMake project in one guided run. CMake is an import and refresh input, not a build or certification runtime. For a normal project, the initial import is one command:

rbit import cmake .

import cmake derives the initial build plan, records the reference binary, and creates empty per-source review shards. It then materializes the reviewed source tree, performs one bounded configure—never a project build—and atomically commits the closed graph and its initial TU review shards. It uses Unix Makefiles on POSIX or the authenticated NMake Makefiles frontend on native Windows, plus compile_commands.json and the reviewed reprobit-target-plan.json. It does not edit CMakeLists.txt.

The guided import derives only facts it can check: target mappings, empty initial intervention/proof records, the protected reference digest, and the compiler/linker commands CMake exposes. It does not guess entropy interventions. rbit status . keeps every missing item visible afterwards.

The simplest setup passes the real CMake target name to rbit init --target, so the default rebuilt-output and reference filenames follow it. Use --target program=your_cmake_target during import only when the ReproBit ID intentionally differs and its declared artifact still matches the real output:

rbit init . --target program --artifact build/app.exe --oracle reference/program.exe
# After setup, source review, and placing the reference binary:
rbit import cmake . --target program=app

If the import fails, the generated scaffold is removed and the diagnostic workspace is retained for inspection.

After adding, removing, or renaming source files in an imported project, begin with rbit source preview .. When the change is compatible, preview points directly to rbit import cmake . --refresh. Refresh stages the new source list and CMake records, preserves compatible per-source adjustments and checks, resets changed steps, retires removed steps, verifies every target from scratch, and publishes the records, verified outputs, and report as one complete passing update. It refuses ambiguous compiler steps and any candidate that fails cold verification. The saved CMake program, configuration, timeout, repeated --cmake-define values, and directive inputs are replayed automatically; explicit refresh options replace those saved values. The CMake workflow gives the full sequence.

Use --clear-cmake-defines or --clear-directive-inputs with --refresh when the refreshed graph should replace one of those saved lists with no values.

Refresh accepts --jobs, --initialization-timeout, --compile-timeout, --link-timeout, and --cleanup-timeout for its build from scratch. These options require --refresh; --timeout controls the separate CMake configure.

rbit graph configure

Create a fresh CMake metadata tree without building. Together with graph extract this is the two-step form of import cmake for CI or unusual projects:

rbit graph configure . \
  --workspace-root .reprobit-state/import \
  --toolchain-root /opt/toolchains/msvc42 \
  --compiler-transport /opt/toolchains/msvc42/wine/x86/cl \
  --resource-transport /opt/toolchains/msvc42/wine/x86/rc \
  --cmake-define FEATURE_SET=classic

graph configure reports the exact configured/effective roots, target plan, compile database, effective-source digest, configure log, command digest, and duration. It also prints the complete graph extract command for that exact workspace. It refuses a non-empty workspace and detects any source mutation during CMake configuration. Repeat --cmake-define NAME=VALUE for ordinary CMake cache settings; the same validation applies to guided import.

rbit graph extract

Record direct compiler and linker steps from the CMake tree that graph configure produced:

rbit graph extract . \
  --configured-build-root .reprobit-state/import/build \
  --effective-source-root .reprobit-state/import/source \
  --effective-source-digest SHA256_FROM_CONFIGURE \
  --toolchain-root /opt/toolchains/msvc42 \
  --directive-input program=oldnames.lib
rbit validate .
rbit explain .
rbit cost .

Replace SHA256_FROM_CONFIGURE with the digest reported by graph configure. graph extract reads expanded compile commands, resource rules, response files, and link commands; converts physical paths into ${SOURCE}, ${BUILD}, and ${TOOLCHAIN} seats; rejects unbound producers and paths; and transactionally publishes reprobit/producer-graph.json. Schema v3 binds the declared direct source inputs, toolchain lock, logical-path profile, exact target set, and terminal artifact paths; the source manifest and build plan separately bind current source contents. Certification reloads those documents and never executes CMake. Re-extract only when a graph input or other command/build authority changes. Repeat --directive-input TARGET=LIBRARY for reviewed linker-only library edges discovered in COFF .drectve sections. The value must be a known target and one bare library name; paths, duplicate declarations, and implicit runtime authorization are rejected. When an edge is missing, the direct runtime emits copy/paste-ready flags for a new explicit extraction.

rbit validate

Check every saved project file:

rbit validate .

validate loads every saved JSON file, rejects duplicate keys and IDs, checks cross-document references and dependency cycles, compares current files with their recorded hashes, renders declarative overlays in memory, and checks effective TU digests. It never runs a build. It is the command that checks source bytes against saved project records; explain and cost inspect the committed metadata only.

rbit cost

Show intervention cost totals:

rbit cost .

The score measures distance from an ordinary build; see the cost model for the fixed categories and accounting rules. The text output names the cost model version and points to rbit explain for the per-intervention view.

rbit status

Show what is ready and the next project setup step:

rbit status .

status checks that each saved project file exists and that every JSON record parses; it does not validate schemas or cross-file agreement until every file is present (then it runs the same check as validate). It also checks that this machine can find the remembered compiler and the required backend tools. These availability checks do not launch the execution probe; use rbit doctor . --execute-probe to exercise it. Rows marked [ ] are missing; [!!] marks a file that exists but cannot be read and points to validate. The exit status is 1 until every check passes.

rbit clean

Remove inactive workspaces; cache and reports are opt-in. Successful workspaces are removed automatically; failed ones are kept so you can diagnose them. Check the space ReproBit manages with state status, then preview cleanup before removing anything:

rbit state status .
rbit clean . --preview
rbit clean .

clean removes inactive workspaces but keeps the reusable incremental cache and saved reports. The following preview includes ordinary inactive-workspace cleanup and the cache data left by older ReproBit code, and keeps the current cache:

rbit clean . --obsolete-cache --preview

The full-cache and saved-report selections are separate alternatives:

rbit clean . --cache --preview
rbit clean . --reports --preview

Use --cache only when you intend to clear incremental and repair-search cache entries. With no age it clears them all; use --older-than-hours 24 to keep recent workspaces and cache entries. Active runs are never removed. The --keep-workspace option of build, verify, repair, and import cmake changes which run workspaces are retained in the first place (on-failure by default).

rbit explain

Explain saved interventions:

rbit explain .
rbit explain . --intervention intervention-id

explain lists interventions and their fixed costs; pass --intervention ID to select one and print it in full. Like cost, it reads the committed metadata only, so it remains useful while source bytes are being edited. A project with no saved interventions says so explicitly. An unknown ID is an error that lists the known IDs.

rbit repair

Use this after editing a file in a project that already matched exactly. This is the complete maintenance workflow, including for a shared header used by many source files:

rbit repair .

Repair finds all affected work, including changes that cross source-file boundaries. It updates saved compiler choices and function records, and safely narrows or removes old fallback records. When generated declarations affect compiler layout, it checks both source views and tries nearby harmless layouts. A layout change can move other compiler output, so repair rechecks that work in later passes. It then rebuilds every target from scratch and checks the result. There is no manual JSON or TOML recipe to write between these steps.

All work happens in a private workspace. Only an exact, trustworthy result is published, and the changed records, verified binaries, matching debug companions, and report are published together. If repair fails, the source edit remains, while the previously published records and results stay unchanged. The default report is .reprobit-state/reports/report.html; choose another project-relative location when useful:

rbit repair . --report-dir build/reprobit-report

Repair advances in trustworthy order. In each affected source build, it acts on the earliest refusal whose input is still complete, stages a safe change, and then analyzes the project again. Later work is rechecked from the newly valid state on the next pass instead of being guessed from an incomplete one. A broad header edit can therefore take several automatic passes, but still needs only the one command. Progress names the current pass and build phase, shows elapsed time, and carries the last completed adjustment into the next check.

If the from-scratch check exposes a remaining link layout mismatch, repair searches nearby harmless source layouts for that target and checks again. This also stays private, and each retry counts against the same command-wide limits.

The ordinary defaults keep searches bounded. If a report says a search budget was exhausted, these advanced options widen it:

rbit repair . --retune-radius 32 --retune-candidates 2048 \
  --candidate-limit 20000 --discovery-candidates 512 \
  --adjustment-rounds 200

--retune-radius is the farthest declaration-count distance tried per saved compiler choice or source layout (default 8, maximum 64). --retune-candidates caps nearby choices per saved compiler choice or source layout (default 64), while --candidate-limit caps nearby repair choices tested by the whole command (default 256). --discovery-candidates caps fresh choices per affected source file after its saved donors are exhausted (default 64). --adjustment-rounds caps saved-guidance adjustment rounds (default 24). Larger values can take longer, but never relax what repair may change or the final proof. The complete limits are in the generated option table.

For added or removed files, start with source preview; it prints a safe next command when one is available. For a new project that builds but does not match yet, use discover grind instead of repair.

Functions newly affected by an edit

When an accepted rbit verify or rbit repair completes, it remembers which function bodies were selected. Repair uses that record to notice when an edit also moves a function that never needed special handling before. It can add the source file to its saved repair guidance and create the needed records automatically; it succeeds only after every newly affected function is restored. If no replacement is found within the default budget, raise --discovery-candidates and --candidate-limit and rerun the same command. Do not hand-edit project records.

Repair stops when the edit removed the function entirely, because it cannot restore a function that is no longer present. A project without a previous accepted verification or repair has no baseline for this check, so the final from-scratch verification remains its gate.

rbit build

Incrementally rebuild changed compiler and linker steps without CMake:

rbit build .

build uses the compiler location remembered by rbit setup. It is the fast incremental loop: it reuses a stored result only when every relevant input still matches, then rebuilds the affected compiler steps and their downstream archive or link steps, and finishes by listing each target output with its size. A summary explains what was reused and why each rebuilt step was rebuilt (a step built for the first time on this machine reads not cached on this machine yet (first build of this step)). Use rbit build . --cold for a non-certifying developer build with no cache reads or writes. Both developer modes use the same current source files: edits to already admitted files without affected reviewed interventions can build without changing committed records. An edit that invalidates an intervention still requires repair, including a shared header found in that compiler's recursive inputs. Cold builds resolve those dependencies afresh before applying reviewed transforms. verify always checks the committed source records.

build, verify, repair, and discover grind run independent steps in parallel. Without --jobs COUNT the worker count is the number of CPUs the process may use, capped at 8 (rbit build --help prints the rule as default: the CPUs this process may use, at most 8). Pass --jobs to pin a count; values below one are rejected with exit status 2.

Matched comparison files

If an imported MSVC link asks for debug data, ReproBit automatically writes a matched binary and .PDB inside the sibling reprobit-debug/ directory. For example, the pair for build/GAME.EXE is build/reprobit-debug/GAME.EXE and build/reprobit-debug/GAME.PDB. Tools that read symbols must use those two files together; do not mix the .PDB with the declared build/GAME.EXE. The declared binary remains the only output used for byte-exact certification or release. There are no extra paths to configure, and incremental builds cache and restore both comparison files together. Export the matching source view with source export before running a source-aware comparison tool.

Advanced: incremental cache and build isolation

The built-in MSVC adapter requires a valid local compiler installation, but normal human runs resolve it from rbit setup. Plain build is a non-certifying incremental developer build: the first run populates an immutable project-local CAS, while an unchanged second run restores all nodes without preparing the logical workspace or starting the shared Wine runtime. It emits typed per-node hit/miss events in NDJSON and a compact text/NDJSON summary with hit, miss, elapsed-time, invalidation, and backend-runtime start count. Use build --cold to bypass and construct no cache state.

rbit verify

Build every target from scratch and check exact bytes and trust evidence:

rbit verify . --report-dir build/reprobit-report

verify always builds from scratch, has no warm/cache mode, and never opens the cache. It writes the trust report as canonical JSON plus self-contained HTML. When targets differ, the final message names them rather than reporting only a count. Exit status 1 means the result did not satisfy the authenticity policy.

Reading the report

The Binary explorer page connects intervention costs to addresses, generated source, and the steps that produce each change. Select an address band or search for a function, then inspect its rendering and related changes. See the binary explorer guide for coordinate meanings and coverage.

Open build/reprobit-report/report.html in a browser. Start with the overall result and target summaries: they separately show whether the bytes match, the saved adjustments passed their logic checks, the output came from the declared toolchain, and the build started from scratch. Charts summarize build work and adjustment cost when those details are available. Exact symbols, commands, receipts, and canonical JSON stay available in collapsed Advanced sections.

Advanced: override machine paths and timeouts for one run
rbit verify . \
  --toolchain-root /opt/toolchains/msvc42 \
  --compiler-transport /opt/toolchains/msvc42/wine/x86/cl \
  --resource-transport /opt/toolchains/msvc42/wine/x86/rc \
  --initialization-timeout 600 \
  --compile-timeout 600 \
  --link-timeout 900 \
  --cleanup-timeout 10 \
  --report-dir build/reprobit-report

The two transport options are supplied together on macOS and Linux. Native Windows rejects those POSIX selectors. The initialization, compile/resource, librarian/linker, and cleanup deadlines are independently bounded; their defaults are 600, 600, 900, and 10 seconds. The same options apply to build, repair, and discover grind; see advanced execution options.

Advanced: proof details

verify seals each reference binary before execution, builds in a new run directory, audits current-run producer and intervention evidence, performs literal comparison, and writes canonical JSON plus self-contained HTML. The two transport options are only needed for an explicit POSIX override. Before preparing a native producer arena it reruns the bounded fresh-LUID lineage-drive probe and fails closed unless the host can admit a suspended producer and preserve its drive through all producer descendants. For a project-level source_overlay_graph, ReproBit derives a declaration counterfactual before admitting effective primary products. Declaration-only leaves require no extra compile. Strict semantic-delta leaves audit their exact source owners; a strict header conservatively audits every ordinary compiler because include exposure is not independently sealed. Each invocation is covered by the compile timeout, and effective overlay receipts can carry certified-project-overlay only after this sparse evidence passes.

The project authenticity policy is authoritative. A command-line policy override may only narrow acceptance; it cannot silently broaden a clean project to accept quarantine. Similarly, target and toolchain overrides are checked against committed project identities.

rbit discover init

Create a small automatic search plan without compiling. This is the expert entry point for precise control over one function:

rbit discover init . \
  --source src/widget.cpp \
  --symbol '?Transform@Widget@@QAEHH@Z' \
  --reference reference/widget.obj

init finds the matching compile step and writes a four-state plan (reprobit/discovery.json by default) for discover grind --expert-plan.

rbit discover run

Run a bounded request file (advanced). discover run REQUEST is a broader resumable campaign. It reports whole-function, private-donor, and same-symbol mosaic proposals but does not save them. Raw proposals are not accepted by certification commands; candidate exploration stays in ignored state. See the discovery guide for the request format, incremental behavior, progress events, and reports.

rbit discover clean

Preview or remove one advanced discovery campaign's reusable state:

rbit discover clean REQUEST --preview
rbit discover clean REQUEST

Cleanup removes the campaign's marker-owned reusable state and keeps the reports. Pass the same --state-directory used by the campaign when it was customized. Cleanup refuses state shared by several request files unless --all-requests is given; preview that combined cleanup before removing it.

rbit discover grind

Search a bounded, project-wide set of low-cost adjustments. Use discovery when a new project's first working build does not yet match its reference. (For a later regression in a project that was already exact, use rbit repair ..) The default is a read-only preview; repeat fresh proofs and save only when you approve the result:

rbit discover grind .
rbit discover grind . --accept-progress  # save proven work; follow its printed next step
rbit discover grind . --accept-exact     # require an exact project before saving anything

The printed approval, continuation, and verification commands preserve any execution overrides you supplied, including compiler and Wine paths, worker count, and timeouts. This also applies to commands in the review reports and to --expert-plan runs. Automatic defaults are omitted so ordinary follow-ups stay short.

Project-wide grind needs project-owned reference .obj files; it cannot derive them from the reference executable alone. Put those objects under reference/ and name them after the source filename without its extension—for example, src/widget.cpp maps to reference/widget.obj—or use the exact translation-unit ID, or pair them explicitly with --reference-object TU=PATH. Before compiling, the preview reports how many eligible compiler steps have an object, how many are missing one, and how many functions it selected. Detailed pairings and skip reasons remain in the report and NDJSON result. The preview tries a small round-robin sample across eligible source files (--max-symbols) and keeps its summary at .reprobit-state/reports/grind/project/report.html. Each outcome links to a detailed decision report and a persisted bounded plan. Exact previews show the copyable, platform-quoted approval command. If the whole project is not exact, the report can instead offer --accept-progress for functions that matched their project-owned reference objects and passed fresh logic checks. It saves those adjustments one at a time and may itself reach an exact project. Follow the printed next step: run another preview if mismatches remain, or run rbit verify . after an exact result. --accept-exact is the stricter path: it publishes nothing unless the current candidate makes the complete project exact. Review changed files in git diff. Saved local progress does not prove the complete project; only a fresh byte-exact result does. Exit status 1 means nothing was found or nothing was saved.

The narrow save paths rerun the logic checks and rebuild from scratch: --accept-progress saves only locally proven function adjustments; --accept-exact saves only a complete byte-identical result.

With --expert-plan reprobit/discovery.json the command evaluates only the plan written by discover init. It writes .reprobit-state/reports/grind/report.html; an exact preview includes its own fresh approval command, while a locally proven result offers the progress approval command. See the discovery guide for both workflows.

rbit state status

Show retained runs, cache, reports, active leases, and disk usage:

rbit state status .

state status reports reusable build and repair-search caches separately from cache data left by older ReproBit code. It names the newest retained runs and their outcomes, keeps a long run list brief, and prints the safe cleanup command when it finds any. NDJSON includes the complete run list.

rbit report

Validate JSON and render self-contained HTML from an existing report:

rbit report build/reprobit-report/report.json

report strictly re-reads canonical report JSON before rendering HTML. The input must be an existing file, and the HTML output must be a different path so the canonical JSON cannot be overwritten.

rbit cmake-module

Print the packaged CMake module path:

rbit cmake-module --file

cmake-module prints the installed module directory, or the complete ReproBit.cmake path with --file. The module is used only during CMake import or refresh; normal build and verify runs do not load it.

Exit status

Every command follows one contract, enforced in reprobit.cli.main and the individual handlers:

Code Meaning Commands that return it
0 The command completed and its result is ready, clean, or accepted. all
1 An honest negative, not an error: the checks ran and the answer is "not yet". status (project not ready), doctor (a check failed), setup (a backend check failed), verify (result not accepted under the policy), discover grind (nothing found or nothing saved)
2 Any error: usage errors, --jobs below one, a CLIError, an unreadable file, or any unexpected exception. The message starts with error:. all
130 Interrupted with Ctrl-C; active child processes were asked to drain. all

A bounded grind can honestly find no useful new authority, so that outcome is 1. Repair starts from an already-exact project and promises to restore it; if it cannot prove a safe complete repair, it refuses the operation as an error and returns 2 without publishing partial authority or outputs.

Machine-readable output

With --format ndjson, every line on standard output is one JSON object and nothing else is written there (diagnostics that text mode sends to standard error become events too). Keys are sorted, non-ASCII is kept, and NaN is rejected. Invalid arguments are emitted as one error event too, so automation does not need a separate parser for usage failures. --help and --version remain ordinary human-readable text. Every object carries:

  • event - the event name from the table below;
  • message - human-readable text for command results and diagnostics;
  • schema_version - 1; consumers should reject an unknown version.

Progress is streamed as workflow_progress (phase started, finished, failed, heartbeat) and producer_progress (unit finished, cache hit, cache miss) events with the fields of reprobit.progress.ProgressEvent: sequence, kind, phase, message, elapsed_seconds and, when present, completed, total, node_id, reason. Progress messages retain machine-level detail; text mode replaces internal phase and node names with concise friendly labels.

Events that offer a follow-up command include both next_argv, the exact argument array for automation, and next_command, the same command rendered for a person to copy. Where those fields are part of an event but no follow-up is needed, they are [] and null.

Command events (from CLIOutput.emit call sites; paths and pydantic models are serialized as strings and JSON objects):

Event Command Fields besides event, message, schema_version
build_complete build cold, nodes+hits+misses (warm) or steps (cold), outputs
cleanup clean active_cache_leases, cache_blobs, cache_records, cache_requested, obsolete_cache_requested, older_than_hours, reclaimed_bytes, removed, repair_search_cache_bytes, repair_search_cache_files, report_bytes, report_files, reports, reports_requested, skipped_active, skipped_recent, skipped_recent_cache_records
cleanup_preview clean --preview active_cache_leases, cache_blobs, cache_records, cache_requested, candidates, next_argv, next_command, obsolete_cache_requested, older_than_hours, reclaimable_bytes, repair_search_cache_bytes, repair_search_cache_files, report_bytes, report_files, reports, reports_requested
cmake_imported import cmake build_plan, next_argv, next_command, nodes, producer_graph, scaffold_transaction_id, translation_units
cmake_refreshed import cmake --refresh added_translation_units, build_plan, cleanup_warning, cold_verified, next_argv, next_command, nodes, outputs, preserved_translation_units, producer_graph, report_html, report_json, reset_translation_units, retired_translation_units, source_manifest, transaction_id
cmake_module cmake-module path
composed_body_ledger verify functions (when saved), outcome, path
cost cost breakdown
discovery_clean discover clean bytes, files, preview, removed, request, requests, shared, state
discovery_complete discover run applied, built, candidate_kinds, cells, proposals, report_html, report_html_digest, report_json, report_json_digest, reused, transaction_id
discovery_grind_complete discover grind --expert-plan added_cost, added_interventions, approval_argv, authority_files, cold_trials, cold_verification_report_html, cold_verification_report_json, compiler_trials, declaration_state, donor_id, exact, function_id, grind_report_html, locally_qualified, next_argv, next_command, project, proposed_interventions, published, qualified_candidates, rejections, report_run_id, report_transaction_id, report_warning, reused_donor, states, symbol, transaction_id
discovery_grind_plan_created discover init next_argv, next_command, plan, project, reference, source, states, symbol, target, transaction_id, translation_unit
discovery_grind_report_warning discover grind --expert-plan artifact, error, error_type, nonfatal, project, published, report
discovery_project_grind_complete discover grind accept_mode, accepted, approval_argv, attempted_symbols, decision_reports, discovered_symbols, eligible_units, exact_symbols, locally_qualified_symbols, max_symbols, next_argv, next_command, outcomes, persisted_plans, project, project_wide, published_progress_symbols, published_symbols, reference_objects, report_html, report_json, report_transaction_id, report_warning, skips, truncated_symbols, verify_argv
discovery_project_grind_report_warning discover grind error, error_type, nonfatal, project, report, symbol, translation_unit
doctor_check doctor component, detail, name, passed, required
doctor_result doctor backend, executed_probe, passed
error any error_type, exit_code, notes (when available)
hint cost, explain
incremental_build_summary build (warm) elapsed_seconds, hit_rate, hits, invalidations, misses, producer_hits, producer_misses, published_comparison_pairs, published_targets, runtime_init_count, transform_hits, transform_misses, unchanged_comparison_pairs, unchanged_targets
initialized init changed_paths, next_argv, next_command, project_id, project_root
interrupted any error_type, exit_code
intervention explain beneficiaries, cost, cost_class, dependencies, id, kind, rationale, scope, units
intervention_summary explain interventions
producer_graph_configured graph configure certification_runtime, command_digest, compile_database, configure_log, configured_build_root, duration_seconds, effective_source_digest, effective_source_root, next_argv, next_command, project_plan, target_plan, toolchain_root
producer_graph_extracted graph extract, import cmake certification_runtime, extractor, graph_digest, nodes, output, roles, skipped_translation_units, transaction_id, translation_units
project_readiness status checks, completed, next_argv, next_command, next_instruction, ready, total
repair_cleanup_warning repair project, workspace
repair_complete repair adjustment_rounds, admitted_translation_units, changed_records, cleanup_warning, compiler_candidates, discovered_actions, donor_retunes, exact, measured_checks, project, reauthored_actions, refreshed_checks, removed_donors, repair_passes, repaired_translation_units, replayed_candidates, report_html, report_json, retired_actions, source_inputs, source_retunes, transaction_id
repair_refused repair failure diagnostic fields, phase
report_written report clean, html, input, total_cost
setup setup backend, backend_failures, environment_ready, next_argv, next_command, next_instruction, profile, project_ready, readiness, toolchain_lock, toolchain_lock_created, toolchain_root
source_exported source export cleanup_warning, interventions, path, preserved_paths
source_locked source lock entries, next_argv, next_command, next_instruction, output, producer_graph_invalidated, selection, source_manifest_digest, transaction_id
source_preview source preview added, after_source_manifest_digest, authority_checked, authority_error, before_source_manifest_digest, changed, checked_overlay_outputs, classic_preflight_checked, cmake_import_command, cmake_refresh_required, entries, membership_transition_blocked, next_argv, next_command, producer_graph_invalidation_required, removed, repair_required, selection, stale_translation_units, unchanged, up_to_date
source_regenerated source regenerate applied, changes, documents, next_argv, next_command, transaction_id
state_status state status cache_active_leases, cache_blobs, cache_bytes, cache_current_records, cache_files, cache_obsolete_records, cache_records, cache_stale_leases, repair_ledger_bytes, repair_ledger_files, repair_search_cache_bytes, repair_search_cache_files, report_bytes, report_files, root, run_bytes, run_files, runs, total_bytes, total_files
toolchain_locked toolchain lock input_trees, output, profile, runtime_files, tools, transaction_id
toolchain_provisioned toolchain provision next_argv, next_command, profile, root, saved
validated validate interventions, project_id, proofs, targets
verification verify accepted, exact_targets, origin_integrity, policy, quarantine_actions, quarantine_bytes, report_html, report_json, target_results, targets, total_cost, verdict
workspace_gc_hint build, verify project
workspace_retained build, verify, repair, import cmake outcome, path

error and interrupted are the only events with an exit code other than 0 or 1 attached; their error_type names the Python exception class (CLIError for expected failures).