Skip to content

Add a root whitaker binary behind an internal library boundary (3.5.1) - #356

Draft
leynos wants to merge 5 commits into
harden-lint-configfrom
3-5-1-root-whitaker-binary
Draft

Add a root whitaker binary behind an internal library boundary (3.5.1)#356
leynos wants to merge 5 commits into
harden-lint-configfrom
3-5-1-root-whitaker-binary

Conversation

@leynos

@leynos leynos commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Execution plan for roadmap item 3.5.1 — add a root whitaker binary and move
the current installer behaviour behind an internal library boundary.

Plan document: docs/execplans/3-5-1-root-whitaker-binary.md

No production code changes. This PR is the plan only, and needs approval
before implementation begins.

What the plan delivers

A real whitaker binary with install and ls, doing what
whitaker-installer and whitaker-installer list do today — while
whitaker --all keeps working by forwarding to cargo dylint.
whitaker check and whitaker doctor remain with their own roadmap items.

Five milestones: extract the Dylint driver library (EP-M0), promote the
installer orchestration into its library (EP-M1), build the binary
(EP-M2), add binstall metadata and reserve the crates.io name (EP-M3),
then the ADR and documentation (EP-M4).

Why revision 2 looks different from a first draft

The plan was stress-tested by a six-perspective design review before
submission. Three findings changed the architecture, and the review is worth
knowing about when reading the Decision log.

The root package cannot be published. Verified directly:

$ cargo package -p whitaker --no-verify --allow-dirty
error: no matching package named `rustc_ast` found
warning: manifest has no description, license, ... or repository

It depends on four publish = false compiler-shim crates. So
cargo install whitaker — the plan's headline outcome — was unreachable.
Extracting the Dylint driver library into crates/whitaker_lint_core is
therefore a precondition rather than a contingency, and it is now EP-M0.
That also makes the root package testable, so CARGO_BIN_EXE_whitaker
becomes available to the end-to-end tests, and it stops ortho_config
propagating into eleven lint crates.

The whitaker name is already taken. installer/src/wrapper.rs:105
writes an executable named whitaker into the user's bin directory, and
Makefile:9 prepends ~/.cargo/bin while Makefile:6 appends
~/.local/bin — so a cargo installed binary deterministically shadows it.
That would break whitaker --all, which docs/users-guide.md documents as
the primary workflow and which this repository's own make lint runs, with
no replacement until 3.5.2. The binary now forwards unrecognized arguments to
cargo dylint.

Both original verification obligations were vacuous. Nothing in the
repository ever inverts a release-asset name, and both documented flag
conflicts are enforced by clap before any repository-owned routing code runs.
Proving properties of an unreachable branch is not evidence, so both were cut
and recorded as such. They are replaced by argv-classification totality and
disjointness — genuinely new logic introduced by the forwarding behaviour —
bounded by Kani and closed unbounded by Verus, each with a required negative
control.

Open questions for the reviewer

Three items are flagged in the Decision log rather than settled:

  • D-6 — whether ortho_config earns its place at this milestone, given
    that NoOpLocalizer does not translate, so the dependency buys a one-line
    call-site difference until 3.6.4.
  • D-7googletest and pretty_assertions are authorized by the task
    brief but the sibling plan for 7.3.1 ruled the other way, and neither crate
    is used anywhere in the workspace today.
  • is_display_request's exact signature needs confirming before Stage B
    writes red tests against it.

Validation

make markdownlint and make nixie pass. make check-fmt, make typecheck
and make lint are unaffected — this change is documentation only.

References

🤖 Generated with Claude Code

leynos and others added 3 commits August 21, 2026 16:23
Draft the execution plan for roadmap item 3.5.1: add a real `whitaker`
binary at the root package and move the current installer orchestration
behind an internal library boundary.

The plan places the CLI domain, ports, and adapters in a new
`crates/whitaker_cli` crate rather than in the root package, because the
root package's library requires `feature(rustc_private)` and is excluded
from `make test` by `TEST_EXCLUDES`. The root `src/main.rs` becomes a
thin composition root.

Scope is limited to `install` and `ls`; `check` and `doctor`, the
configuration model, and the deprecation shim remain with their own
roadmap items.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A six-perspective review invalidated the first draft's structural bet.
`cargo package -p whitaker` fails: the root package depends on four
`publish = false` rustc shim crates and lacks crates.io metadata, so
`cargo install whitaker` was unreachable. Extracting the Dylint driver
library into `crates/whitaker_lint_core` is therefore a precondition,
not a contingency, and it is now milestone EP-M0. That removes the need
for a separate CLI crate, makes `CARGO_BIN_EXE_whitaker` available to
the end-to-end tests, and confines `ortho_config` to the CLI binary.

Record the `whitaker` name collision the first draft missed: the
installer generates an executable named `whitaker` that a `cargo
install`ed binary deterministically shadows, breaking `whitaker --all`
and this repository's own `make lint`. The binary now forwards
unrecognized arguments to `cargo dylint`.

Cut both original verification obligations as vacuous. Nothing inverts
a release-asset name, and clap rejects the flag conflicts before any
repository-owned routing code runs. Verify argv classification
totality and disjointness instead, bounded by Kani and closed unbounded
by Verus. Settle exit codes at 0, 2, and 1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, we are unable to review this pull request

The GitHub API does not allow us to fetch diffs exceeding 300 files, and this pull request has 430

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Warning

Your free Security trial is over. An organization admin can activate billing to continue.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Warning

Your free Security trial is over. An organization admin can activate billing to continue.


Comment @coderabbitai help to get the list of available commands.

codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No quality gates enabled for this code.

@leynos
leynos changed the base branch from main to harden-lint-config August 21, 2026 17:12
@leynos leynos changed the title Plan: add a root whitaker binary behind an internal library boundary (3.5.1) Add a root whitaker binary behind an internal library boundary (3.5.1) Aug 24, 2026
leynos added 2 commits August 24, 2026 04:01
Move compiler-private driver code and its tests into the non-publishable
`whitaker_lint_core` package so the root package can become a normal,
publishable CLI package.

Migrate all in-tree lint consumers and templates to the internal package,
and retain the moved tests through a dedicated feature-free core pass. This
avoids Cargo feature-unification linkage failures without weakening the
all-feature Dylint validation.
Move command routing and installation flow behind
`whitaker_installer::orchestration` while keeping the legacy binary as a
small composition root.

Add a normalized `--dry-run` output snapshot to preserve the existing
installer contract through the relocation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant