WIP: The pre-push gate runs tests but not clippy, so trivial lints are only caught after a 30-minute CI round trip #544

Draft
toasterson wants to merge 4 commits from claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli into main
Owner

Anima work item 019fe251-729a-7cd3-91ca-c488c403165f.

Observed across three separate work items on 2026-08-08. CI runs clippy with -D warnings on rust 1.96.0; the in-session pre-push gate (crates/anima-runner/src/test_gate.rs) runs only cargo test for touched crates. So an agent finishes a turn believing it is done, the diff is pushed, CI is dispatched, the item waits through the queue, and roughly half an hour later it fails on a lint the compiler could have reported in seconds.

Every failure of this class so far has been mechanical, with the fix printed verbatim in the error:

  • WI-496 (5fb16a4, run aef110d9) — three lints, all in crates/anima-server/src/services/runner.rs: collapsible_if at 2058, and clone_on_copy on a Uuid at 2062 and 3960 (try dereferencing it: *session_id.as_uuid()). The session had reported "426 tests passing, build clean, no warnings" the turn before.
  • Run fd58c990 (0c9ea54d) — one lint: assign_op_pattern at crates/anima-db/src/repo/workitem_phase_history.rs:259, replace it with: elapsed -= credit.

The cost is not the lint. It is that the feedback arrives after the slowest loop in the system. Solstice's rust queue regularly holds items 15+ minutes before a run starts and the run itself takes another 10-15, so a one-character fix costs the better part of an hour of wall clock plus a full re-dispatch, and it consumes a turn against the item's retry budget on the way through.

Required change: the pre-push gate must run clippy with the same flags and the same toolchain as CI for the touched crates, and treat a lint failure the same way it treats a test failure — feed the output back into the session so the agent fixes it in-turn, and skip the push. Concretely, cargo clippy --all-targets -- -D warnings, matched to whatever .solstice/job.sh pins, so the two cannot drift.

Two constraints:

  1. The toolchain must match CI exactly. CI currently resolves rust 1.96.0. A gate that lints against a different rustc will either miss failures or invent ones, and a gate that invents failures is worse than no gate — it will park healthy work. This is the same hazard tracked in PR #385 (CI lints against an unpinned toolchain); the gate and CI should read their version from one source.

  2. A lint failure is a work failure, not an infrastructure failure — genuinely attributable to the item, so unlike WI 019fe18f's infrastructure class it should count against the retry budget. Keep the two paths distinct; do not fold lint failures into the infra classification being added there.

Acceptance: a diff introducing let x = y.clone() on a Copy type fails the pre-push gate in-session with the clippy output as feedback, and never reaches CI. A clean diff still pushes. The gate's clippy invocation and CI's resolve to the same rustc version, verified by a test that fails if they diverge.

Related: WI 019fe18f (gate misattributing infrastructure faults), akh-medu's lint-tax item covering the same waste on the akh side.

Anima work item `019fe251-729a-7cd3-91ca-c488c403165f`. Observed across three separate work items on 2026-08-08. CI runs clippy with `-D warnings` on rust 1.96.0; the in-session pre-push gate (`crates/anima-runner/src/test_gate.rs`) runs only `cargo test` for touched crates. So an agent finishes a turn believing it is done, the diff is pushed, CI is dispatched, the item waits through the queue, and roughly half an hour later it fails on a lint the compiler could have reported in seconds. Every failure of this class so far has been mechanical, with the fix printed verbatim in the error: - WI-496 (`5fb16a4`, run `aef110d9`) — three lints, all in `crates/anima-server/src/services/runner.rs`: `collapsible_if` at 2058, and `clone_on_copy` on a `Uuid` at 2062 and 3960 (`try dereferencing it: *session_id.as_uuid()`). The session had reported "426 tests passing, build clean, no warnings" the turn before. - Run `fd58c990` (`0c9ea54d`) — one lint: `assign_op_pattern` at `crates/anima-db/src/repo/workitem_phase_history.rs:259`, `replace it with: elapsed -= credit`. The cost is not the lint. It is that the feedback arrives after the slowest loop in the system. Solstice's `rust` queue regularly holds items 15+ minutes before a run starts and the run itself takes another 10-15, so a one-character fix costs the better part of an hour of wall clock plus a full re-dispatch, and it consumes a turn against the item's retry budget on the way through. Required change: the pre-push gate must run clippy with **the same flags and the same toolchain as CI** for the touched crates, and treat a lint failure the same way it treats a test failure — feed the output back into the session so the agent fixes it in-turn, and skip the push. Concretely, `cargo clippy --all-targets -- -D warnings`, matched to whatever `.solstice/job.sh` pins, so the two cannot drift. Two constraints: 1. **The toolchain must match CI exactly.** CI currently resolves rust 1.96.0. A gate that lints against a different rustc will either miss failures or invent ones, and a gate that invents failures is worse than no gate — it will park healthy work. This is the same hazard tracked in PR #385 (CI lints against an unpinned toolchain); the gate and CI should read their version from one source. 2. **A lint failure is a work failure, not an infrastructure failure** — genuinely attributable to the item, so unlike WI `019fe18f`'s infrastructure class it *should* count against the retry budget. Keep the two paths distinct; do not fold lint failures into the infra classification being added there. Acceptance: a diff introducing `let x = y.clone()` on a `Copy` type fails the pre-push gate in-session with the clippy output as feedback, and never reaches CI. A clean diff still pushes. The gate's clippy invocation and CI's resolve to the same rustc version, verified by a test that fails if they diverge. Related: WI `019fe18f` (gate misattributing infrastructure faults), akh-medu's lint-tax item covering the same waste on the akh side.
toasterson force-pushed claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli from 2b6cb71259 to 0fd4609046 2026-08-09 10:34:13 +00:00 Compare
toasterson force-pushed claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli from 92bc02f03a to 533aa978ad 2026-08-09 21:00:20 +00:00 Compare
toasterson force-pushed claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli from 533aa978ad to d4da649d0c 2026-08-10 13:59:06 +00:00 Compare
toasterson force-pushed claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli from d4da649d0c to 40427cd545 2026-08-10 21:09:18 +00:00 Compare
toasterson force-pushed claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli from 40427cd545 to ba2346a7e0 2026-08-16 09:32:27 +00:00 Compare
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli:claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli

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-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git rebase main
git switch main
git merge --ff-only claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git rebase main
git switch main
git merge --no-ff claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch main
git merge --squash claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch main
git merge --ff-only claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
git switch main
git merge claude/wi-019fe251-the-pre-push-gate-runs-tests-but-not-cli
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!544
No description provided.