§§1-9 were written on fabi-Hyrican-PC. On the other desktop the ~/.sylph-*
credentials do not exist, the Pi does not resolve, and stable is 1.90.0 rather
than the 1.98.1 §8 records -- so §8.2 (fetch the WASM bundle) and §8.4 (Phase 7)
cannot be run from here at all. Says which of the four steps can.
Measured rather than carried over: protection holds (10/10), fmt is 774 hunks
across 154 files, check-citations is 19, and the tests are 207/0/14 across 30
suites. Two of those need reading carefully:
* clippy DIVERGES. The runner is rustc 1.98.1 -- read out of job 794's log,
not assumed -- and is clean; here 1.90.0 exits 101 on only_used_in_recursion
at vfs.rs:85. That is #15 ceasing to be theoretical. It is NOT evidence that
CI's green is fake, which is the §7 lesson-5 inference in the other
direction.
* the test tally matches to the unit while measuring something else. 15
*_disc.rs files resolve disc_root() through a hardcoded absolute path, so
unsetting SYLPHEED_DISC does not skip them: the disc suites RAN here (1936 s,
mesh_consistency_disc alone 1220 s) and skipped on CI (2.4 s total) -- and
both report 207/0/14, because the skip path returns from a test that still
passes. Good news for #14, since this run is the stronger evidence; and worth
an issue, since SYLPHEED_DISC looks like a control and is not one.
I got that last one wrong first -- inferred "the counts cannot match" from "the
fallback resolves", which is §7's shape a sixth time, recorded as such.
Also: a plain `git clone` of this repo fails three ways on the pack that still
carries the 545 MB; --filter=blob:none works. And §6's tokio claim was
challenged and survived -- every use is inside a #[cfg(test)] module.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Written to be read cold by a session with no context: what is established
versus what is someone's claim, which of the four actors the gate actually
binds, and what is in flight but unpushed.
The transferable part is §7 -- one failure shape recurred five times in two
days across two agents and the assistant: a property inferred from something
ADJACENT to it rather than tested directly. Protection from a settings page,
reachability from a DNS record, a label count from a grep that matched the
function definition, Gitea's host from a DNS lookup, and a clippy version from
rustfmt output parity. The last is the sharpest: rustfmt 1.8.0 and 1.9.0, nine
months apart, both emit 774 hunks here, so formatting parity carries no
information about which clippy ran -- and the conclusion drawn from it (that
CI's green was cached or ungated) was wrong in a way that would have sent
someone chasing a phantom.
`ascii_runs` in movie_manifest.rs had a nested `else { if .. }`. Clippy's
`collapsible_else_if` flags it — on some toolchains.
WHY IT WAS NEVER CAUGHT, AND WHY THAT IS THE INTERESTING PART:
clippy::collapsible-else-if @1.92.0 (2025-12-08) -> warn
clippy::collapsible-else-if @1.98.1 (2026-09-01) -> allow
CI installs `dtolnay/rust-toolchain@stable`, which floats. The runner is on
1.98.1, where this lint is allow-by-default, so the Clippy job passed. A local
run on a nine-month-old stable failed on the same bytes. Neither instrument was
broken; "clippy clean" is simply a statement about a toolchain and a date, and
nothing in the pipeline records which. That is #15, and this commit does not fix
it -- it removes one instance of its consequence.
Fixing it rather than pinning, because `else { if }` is worse code on every
version. A tree whose cleanliness is contingent on a release date is the thing
to avoid; agreeing with both toolchains is cheaper than arguing about which one
is right.
⚠️ I FIRST DIAGNOSED THIS WRONG, and the wrong version is worth recording. From
CI's rustfmt reporting 774 hunks and mine reporting 774, I concluded the
toolchains matched, therefore the clippys matched, therefore CI's green must be
a cached or ungated result -- "the frozen splash again". Every step after the
first was false. rustfmt is deliberately output-stable within a style edition;
clippy explicitly moves lints between groups. Measured here afterwards:
rustfmt 1.8.0-stable -> 774 hunks
rustfmt 1.9.0-stable -> 774 hunks (nine months apart, identical)
So formatting parity carries no information about which clippy ran. It is the
same error as reading protection off a settings page or reachability off a DNS
record: a property inferred from something ADJACENT to it. The peer refuted it
by measurement -- `No cache found` in the run log, and `success()` evaluating
'true' in 207 against 'false' in 203 -- rather than by accepting the framing.
Verified on both: 1.92.0 `clippy --workspace -- -D warnings` rc=0 (was 101);
1.98.1 with the lint forced on, 0 sites. rustfmt still 774, so no debt added to
#12. Tests 207 passed / 0 failed / 14 ignored, unchanged.
The lint work added 8 rustfmt hunks. Run 206's Formatting job reports 782
where run 204 reported 774, and the difference is mine — debt added to the
one issue the lint pass argued should not be disturbed. Measured against a
`b6466cb` worktree under the same rustfmt, the tree is back to 774: equal
to baseline, not merely close to it.
Two causes, both interactions rather than mistakes of judgement:
`cargo clippy --fix` writes its replacement on one line. Where the call
sat inside a multi-line method chain that produced
.as_chunks::<2>().0.iter()
which rustfmt wants split across three lines. Seven sites, in
`formats/{audio,vfs,game_data}.rs` and `cli/main.rs`. An eighth was a
`for` header pushed past the width limit; it reads better as two bindings
than as a six-line chain, so that is what it became.
The last one is subtler and was the only file left over after the other
seven were fixed. `ship_capture.rs` had
let mut flush = |base: u32,
size: u32,
and clippy correctly removed the `mut`. That shortens the line by four
characters, so the closure's six continuation parameters were then
aligned four columns too far right — a formatting change caused by a
change on a different line, in a file whose own hunk count is what
exposed it.
Worth recording because it generalises: `--fix` output is not rustfmt
output, and on a tree that is not rustfmt-clean the difference is
invisible in the diff and only shows up as a hunk count moving. The check
that catches it is a count against a same-toolchain baseline, not an
inspection of the patch.
Re-verified after the reformat, since these edits changed real lines:
cargo clippy --workspace -- -D warnings exit 0
cargo test --workspace exit 0 207 passed, 0 failed
cargo fmt --all -- --check 774 hunks == baseline
Refs #12, #13
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McNbzUeq1KRBWs4G6X2YVj
`cargo clippy --workspace -- -D warnings` now exits 0. `cargo test
--workspace` still reports 207 passed, 0 failed, 14 ignored across 30
suites — identical to runs 203 and 204, so none of this changed behaviour.
The workspace total was 73, not the 48 run 204 reported. `-D warnings`
turns a lint into a hard compile error, so `sylpheed-formats` failing
stopped its dependents from ever being built: `sylpheed-viewer` (14) and
`sylpheed-cli` (11) had never been linted by anyone. Clearing formats in
5c35a34 is what made them visible.
formats 43 -> 0 (5c35a34)
viewer 14 -> 0
cli 11 -> 0
export 5 -> 0
Collision surface, measured rather than assumed. Every viewer file
carrying a lint is byte-identical on both `auto/frame-blend-draw-path`
(495 commits) and `auto/port-p6-audio` (366). All eleven cli sites fall
outside every hunk either branch touches. 68 of the 73 sites could not
collide with anything.
The five that can are all in `sylpheed-export`, and three of those are
real:
main.rs:278 `&out` -> `out`, inside frame-blend's hunk -278,12
main.rs:318 `&out` -> `out`, inside port-p6-audio's hunk -303,44
audio.rs:113 an added `#[allow]` in a file frame-blend DELETES
Each is one line. Resolving the first two means taking the branch's
version and re-applying a borrow removal; the third resolves to the
deletion. Flagged here so neither branch owner meets them cold.
Judgement calls, all stated at the site rather than suppressed globally:
* Three `too_many_arguments` in the viewer are false positives.
`draw_viewer_ui`, `poll_loader_channel` and `apply_pak` are Bevy
systems — every parameter is a `Res`/`ResMut`/`EventWriter` the
scheduler injects, so the count is the framework's dependency list and
cannot be reduced without a `SystemParam` struct.
* `cmd_screen_render` (cli, 8/7) is a plain function, so that one is real
if mild; its arguments are the subcommand's flags.
* Two `dead_code` fields in export are serde schema fields. They model
what the on-disc JSON accepts; deleting them would quietly change that.
* `iso_loader.rs` gains a `FrameRx` alias for the ffmpeg frame channel,
which is what "very complex type" was asking for.
A site-local `#[allow]` with a reason is a decision recorded where it
applies: one lint, one function, and any new violation elsewhere still
fails the build. That is not the shape PROTOCOL.md forbids.
Closes#13
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McNbzUeq1KRBWs4G6X2YVj
Run 204 gave this repository its first clippy measurement — 48 errors, 43
of them in `sylpheed-formats`. This clears that 43 to zero under the exact
invocation CI runs, `cargo clippy -p sylpheed-formats -- -D warnings`.
Why this crate first, and why it is safe to touch:
Every one of the 43 sites was checked against the line ranges that
`auto/frame-blend-draw-path` (495 commits) and `auto/port-p6-audio` (366)
actually modify. None of them overlap. Eleven of the fifteen affected
files are byte-identical on both branches, including `mesh.rs` and
`texture.rs`, which carry 28 of the hits between them. The three sites in
`audio.rs`, `ui_layout.rs` and `slb.rs` that live in files those branches
do change fall outside every modified hunk. The collision argument that
defers #12 does not transfer here; it was tested rather than assumed.
It also unblocks a measurement. `-D warnings` turns a lint in this crate
into a hard compile error, so its dependents never build — `sylpheed-cli`
and `sylpheed-viewer` have never been linted at all, and viewer is the
largest crate in the workspace. Both depend only on `sylpheed-formats`
(`sylpheed-export` pins it from a git tag instead), so this commit is what
makes their real counts knowable.
38 applied by `cargo clippy --fix` — chunks_exact_to_as_chunks,
manual_div_ceil / is_multiple_of / range_contains, unnecessary_map_or,
needless_borrow, let_and_return, dead_code, unused_mut/variables.
Purely local expression rewrites: 38 insertions, 39 deletions.
2 by hand: a doc continuation that markdown was parsing as a list, and
`d / frame` behind a `frame > 0` guard becoming `checked_div`.
3 `#[allow(clippy::too_many_arguments)]` with a stated reason.
On those three allows: 8 parameters against a threshold of 7, in the mesh
anchor path. The real fix is a shared params struct across
`anchor_pool_mesh`, `validate_block` and `validate_block_report` — the
latter two take the same eight arguments and one delegates to the other —
which is a change to the decoder's signatures and belongs to whoever owns
that path, not to a CI-lint pass.
This is not the shape PROTOCOL.md forbids. `continue-on-error` suppresses
everything, present and future, at the job level, and cannot tell "not
yet" from "no longer". A site-local `#[allow]` with a reason is a decision
recorded where it applies: one lint, one function, and any new violation
anywhere else still fails the build.
`sylpheed-export`'s remaining 5 are deliberately untouched — three of them
sit inside hunks both long-lived branches modify, and that crate blocks
nothing. Left for #13.
Refs #13
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McNbzUeq1KRBWs4G6X2YVj
The two instances already in "Checks that were kind once" were correct
when written and decayed. The third was wrong on its first commit, and it
arrived by a different route: the check and the tree's failure to pass it
land in the same change, so the softening writes itself.
Concretely — the Clippy step had never run (no component in the
toolchain), and the tree is not clippy-clean, so fixing the step and
turning it red are the same commit. The first draft paired the fix with
`continue-on-error: true` and a comment promising removal once the debt
was paid: an expiry date nobody set, in the shape #12's closing line had
already ruled out for rustfmt. Reverted on reading it.
Adds the distinction, a table separating decay from dirty authorship, and
an earlier tell than the mechanical test:
If you are writing the softening in the same commit as the check,
the thing you want is an issue, not a flag.
The mechanical test is unchanged and still correct; this only catches the
same failure sooner, at the keyboard rather than at review.
Refs #12, #13
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01McNbzUeq1KRBWs4G6X2YVj