WIP: CI lints against an unpinned toolchain: -D warnings floats with whatever rustc the image ships #385

Draft
toasterson wants to merge 2 commits from claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d into main
Owner

Anima work item 019f9aa3-88fb-7be0-bf73-c3fe064c0295.

Problem

The workspace has no rust-toolchain.toml. .solstice/job.sh runs:

cargo clippy --workspace --exclude anima-desktop -- -D warnings

against whatever rustc the solstice-rust image happens to carry — today 1.96.0 (2026-05-25). Local dev is on 1.97.1. Clippy's lint set changes between releases, so CI's pass/fail gate is a function of the image, not of the code. A rebuilt image can turn main red with no commit.

Concrete, observed today: cargo fmt --check reports a diff at crates/anima-db/src/repo/thread.rs:569 on clean main under rustfmt 1.97 — 1.96 does not produce it. Confirmed by stashing and re-running. Reformatting to satisfy one version breaks the other. There is no version of the file that satisfies both.

Why this is more than tidiness

It undermines the exit bar. The machine gate consumes a green/red verdict; if that verdict depends on an unversioned image, a red run does not reliably mean "the code is wrong" — which is exactly the failure mode that parked seven WIs on false protoc evidence between 2026-07-11 and 2026-07-25.

It also hid a second error today. Clippy aborts the workspace at the first failing crate, so anima-server's result_large_err was invisible until anima-db's too_many_arguments was fixed (PR #370). Anyone fixing "the" lint locally on a different toolchain gets a different set.

Fix

  1. Add rust-toolchain.toml at the workspace root pinning channel plus the rustfmt and clippy components, so local, Actions, and native all agree.
  2. Make the pinned version the one the solstice-rust image bakes, and treat a bump as a deliberate change with its own PR (lint fallout included).
  3. Decide fmt's status explicitly. Today clippy is blocking and fmt only prints a diff — an inconsistency that has already cost a debugging cycle. Either gate both or neither, and say which in the job script.
  4. Log the resolved rustc/clippy/rustfmt versions in the CI verdict so a lint failure is attributable to a toolchain.

Acceptance

  • rustc --version in a native CI run matches the checked-in pin.
  • cargo fmt --check and cargo clippy -- -D warnings produce identical results locally and in CI on the same commit.
  • Bumping the pin is a reviewable diff, not an image side effect.

Context

Found while clearing the two clippy errors in PR #370, on top of the protoc fix in #369.

Anima work item `019f9aa3-88fb-7be0-bf73-c3fe064c0295`. ## Problem The workspace has **no `rust-toolchain.toml`**. `.solstice/job.sh` runs: ``` cargo clippy --workspace --exclude anima-desktop -- -D warnings ``` against whatever rustc the `solstice-rust` image happens to carry — today `1.96.0 (2026-05-25)`. Local dev is on `1.97.1`. Clippy's lint set changes between releases, so **CI's pass/fail gate is a function of the image, not of the code**. A rebuilt image can turn `main` red with no commit. Concrete, observed today: `cargo fmt --check` reports a diff at `crates/anima-db/src/repo/thread.rs:569` **on clean `main`** under rustfmt 1.97 — 1.96 does not produce it. Confirmed by stashing and re-running. Reformatting to satisfy one version breaks the other. There is no version of the file that satisfies both. ## Why this is more than tidiness It undermines the exit bar. The machine gate consumes a green/red verdict; if that verdict depends on an unversioned image, a red run does not reliably mean "the code is wrong" — which is exactly the failure mode that parked seven WIs on false protoc evidence between 2026-07-11 and 2026-07-25. It also hid a second error today. Clippy aborts the workspace at the first failing crate, so `anima-server`'s `result_large_err` was invisible until `anima-db`'s `too_many_arguments` was fixed (PR #370). Anyone fixing "the" lint locally on a different toolchain gets a different set. ## Fix 1. Add `rust-toolchain.toml` at the workspace root pinning `channel` plus the `rustfmt` and `clippy` components, so local, Actions, and native all agree. 2. Make the pinned version the one the `solstice-rust` image bakes, and treat a bump as a deliberate change with its own PR (lint fallout included). 3. Decide fmt's status explicitly. Today clippy is blocking and fmt only prints a diff — an inconsistency that has already cost a debugging cycle. Either gate both or neither, and say which in the job script. 4. Log the resolved `rustc`/`clippy`/`rustfmt` versions in the CI verdict so a lint failure is attributable to a toolchain. ## Acceptance - `rustc --version` in a native CI run matches the checked-in pin. - `cargo fmt --check` and `cargo clippy -- -D warnings` produce identical results locally and in CI on the same commit. - Bumping the pin is a reviewable diff, not an image side effect. ## Context Found while clearing the two clippy errors in PR #370, on top of the protoc fix in #369.
CI lints against an unpinned toolchain: -D warnings floats with whatever rustc the image ships
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 43s
8a36f64568
Anima implementation session.
toasterson force-pushed claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d from 8a36f64568
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 43s
to 7a7b62f32a
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 1m20s
2026-07-26 07:43:03 +00:00
Compare
toasterson force-pushed claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d from 7a7b62f32a
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 1m20s
to 2e45cf9b87
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 1m7s
2026-07-26 08:24:18 +00:00
Compare
toasterson force-pushed claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d from 2e45cf9b87
All checks were successful
CI / docker (pull_request) Has been skipped
CI / conflict-check (pull_request) Successful in 1m7s
to 9fbaea3878 2026-07-28 12:04:54 +00:00
Compare
toasterson force-pushed claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d from 9fbaea3878 to 1b84c94acb 2026-07-28 12:44:24 +00:00 Compare
toasterson force-pushed claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d from 1b84c94acb to c31b9db73d 2026-07-28 18:23:02 +00:00 Compare
This pull request has changes conflicting with the target branch.
  • .solstice/job.sh
  • crates/anima-core/src/domain/progress_witness.rs
  • crates/anima-db/src/repo/mod.rs
  • crates/anima-db/src/repo/workitem_phase_history.rs
  • crates/anima-runner/src/acp.rs
  • crates/anima-runner/src/git.rs
  • crates/anima-runner/src/quota.rs
  • crates/anima-runner/src/slot.rs
  • crates/anima-server/src/dispatch.rs
  • crates/anima-server/src/health.rs
  • crates/anima-server/src/main.rs
  • crates/anima-server/src/mcp/handlers.rs
  • crates/anima-server/src/services/runner.rs
  • crates/anima-server/tests/deliverable_exit_bar_test.rs
  • crates/anima-server/tests/document_deliverable_test.rs
  • crates/anima-server/tests/turn_failure_test.rs
  • crates/anima-solstice/src/dispatch.rs
  • crates/anima-solstice/src/results.rs
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d:claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git rebase main
git switch main
git merge --ff-only claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git rebase main
git switch main
git merge --no-ff claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch main
git merge --squash claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch main
git merge --ff-only claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git switch main
git merge claude/wi-019f9aa3-ci-lints-against-an-unpinned-toolchain-d
git push origin main
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
toasterson/Anima!385
No description provided.