cargo-explain-build 0.1.0

Stable-first Cargo subcommand for explaining saved build sessions
# cargo-explain-build

`cargo-explain-build` is a stable-first Cargo subcommand for capturing `build`, `check`, `test`, and `run` sessions, then explaining what changed between them.

It does not link against Cargo as a library. The tool shells out to the Cargo binary, saves only stable evidence, and labels uncertain causality as `unknown` instead of overclaiming.

## Status

The current baseline is suitable for a first public `0.1.0` style release candidate, not a complete build profiler.

Implemented today:

- `cargo explain-build run <build|check|test|run> [cargo args...]`
- `cargo explain-build last [--global]`
- `cargo explain-build why [--global] <crate-or-target>`
- `cargo explain-build diff [--global] [<session-a> <session-b>]`
- `cargo explain-build doctor [--global]`

Still intentionally limited:

- no trustworthy per-unit timing analysis on stable
- incomplete build-script package attribution when Cargo does not expose enough stable path evidence
- incomplete causality for non-workspace or filtered units
- no historical env-value capture for `rerun-if-env-changed`

## Install

Before crates.io publication, install from this repo:

```bash
cargo install --path crates/cli --locked
```

After publication, the intended install path is:

```bash
cargo install cargo-explain-build --locked
```

The workspace packages are validated locally with `cargo package --workspace --locked`; the crates.io install path remains a post-publication check until the first release is live.

Check the installed binary:

```bash
cargo explain-build --help
cargo explain-build --version
```

Sessions are stored under `CARGO_EXPLAIN_BUILD_HOME` when set, otherwise `~/.cargo-explain-build`.

## Quick Start

Record a baseline session:

```bash
cargo explain-build run build
```

After changing code, manifests, or build-script inputs, inspect the latest saved session:

```bash
cargo explain-build last
cargo explain-build why my-crate
cargo explain-build diff
cargo explain-build doctor
```

When the current directory belongs to a Cargo workspace, `last`, `why`, `diff`, and `doctor` prefer sessions from that workspace. Use `--global` to inspect the latest session across all workspaces in the shared store.

## Stable-First Evidence

The current implementation depends on:

- `cargo metadata --format-version=1`
- `cargo <cmd> --message-format=json-render-diagnostics`
- build-script output files under `target/**/build/**/output` when they exist
- tool-owned session history for comparison

Because the analysis depends on Cargo JSON events, `cargo explain-build run ...` rejects incompatible `--message-format` values such as `human` instead of silently degrading the report.

Confidence labels are explicit:

- `authoritative`: the command surface changed
- `high-confidence`: stable evidence points at a concrete file or manifest change
- `inferred`: stable evidence shows a downstream rebuild but cannot fully prove the chain
- `unknown`: stable Cargo evidence is not enough to prove the cause

## Command Notes

`run`

- records a new session from `build`, `check`, `test`, or `run`
- saves command, workspace, metadata snapshot, rebuilt units, success, and wall-clock duration

`last`

- renders the latest saved session for the current workspace when possible

`why <crate-or-target>`

- explains the latest saved evidence for one workspace unit
- includes upstream or downstream workspace context when metadata makes that visible

`diff`

- compares the latest workspace session to its previous workspace session
- can also compare two explicit session ids

`doctor`

- calls out missing comparison context, `check` caveats, target-dir or target-triple changes, and broad build-script invalidation hints

## Validation

Primary CI is GitHub Actions on `ubuntu-latest`. It currently runs the same baseline checks the project expects locally:

```bash
cargo fmt --all --check
cargo clippy --workspace --all-targets --locked --offline -- -D warnings
cargo test --workspace --locked --offline
```

Codeberg remains a source mirror today; there is no separate Forgejo/Codeberg CI workflow in this repo yet.

## Release Checklist

Maintainers should follow [docs/RELEASING.md](/Users/sawyer/github/explain-build/docs/RELEASING.md) for the exact verification, packaging, and publish order, then use [docs/FIRST_RELEASE_CHECKLIST.md](/Users/sawyer/github/explain-build/docs/FIRST_RELEASE_CHECKLIST.md) as the final gate before tagging `v0.1.0`.