Repository navigation
fix(ci): unbreak CI after Rust 1.99 and clear October RustSec advisories - #159
Merged
Merged
Conversation
Rust 1.99 deprecates AtomicUsize::fetch_update in favor of try_update. CI runs floating stable with RUSTFLAGS="-D warnings", so since the runners moved to 1.99.0 on Oct 2 every stable job (clippy, test, test-windows, corpus) has failed to compile bookforge-llm. try_update is unstable on the 1.88 MSRV (E0658), so the compiler's suggested rename would break the msrv job instead. Both call sites now go through one private helper that keeps fetch_update behind a single allow(deprecated). Orderings and closures are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows the cfg(not(windows)) block is compiled out, leaving the return as the tail of replace_file, which clippy's needless_return rejects. CI's clippy job runs on Linux and never compiles this block, so only a Windows-local -D warnings gate saw it. Behavior is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rustls 0.23.45 -> 0.23.46 resolves RUSTSEC-2026-0346/0347/0348/0349. quinn-proto 0.11.16 -> 0.11.19 resolves RUSTSEC-2026-0338 through 0342. quinn-proto is only reqwest's optional http3 dependency and is not compiled for any target here, but cargo audit reads every lockfile entry and RustSec is a required check on main. Lockfile-only: two version/checksum pairs, both within the 1.88 MSRV. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zip 8.6.0 carries three advisories against ZipArchive::extract and ZipStreamReader::extract. BookForge never calls either, but RustSec is a required check on main. zip 9.0.5 fixes them and declares rust-version 1.88, matching the MSRV; its new nix dependency is macOS/BSD-only. ZipFile::name() and ZipArchive::file_names() now return ZipResult<Cow<str>>. Names decode lazily (UTF-8, then CP437, which maps every byte), so no name that 8.6 accepted is rejected; only an entry flagged UTF-8 with invalid bytes now decodes as CP437 instead of lossy UTF-8. validate.rs keeps its skip-unreadable-entry behavior. zip 9 also refuses to inflate an entry past its declared uncompressed size, so a lying entry is now rejected at declared size + 1 byte instead of at BookForge's per-entry limit. It reports that as a bare InvalidData I/O error; read_entry now re-raises InvalidData read errors as an EPUB decompression error naming the entry, like its other limit errors. Two tests assert the new message. The running-total test now uses honest entries with a directly built budget, since zip 9 refuses to read a lying entry at all. Adds a regression test for non-ASCII entry names through inspect, read and rebuild. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1/0382 Both advisories were published after this branch's audit last passed: rustls-webpki 0.103.15 could accept distrusted intermediates (RUSTSEC-2026-0382) and webpki-roots 1.0.8 bundled roots that trust distrusted emSign intermediates (RUSTSEC-2026-0381). Lockfile-only: rustls-webpki 0.103.16 and webpki-roots 1.0.10, both within the 1.88 MSRV. cargo audit --deny warnings passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CI on
mainhas failed every day since Oct 2 (last green run: Oct 1), and every PR is blocked. This PR fixes both causes:AtomicUsize::fetch_updatein favor oftry_update. Becauseci.ymlsetsRUSTFLAGS: "-D warnings"for every job, the two calls inbookforge-llm/src/concurrency.rsstopclippy,test,test (windows-msvc)andcorpusfrom compiling.RustSec advisory auditis a required check onmainand fails on 12 advisories inCargo.lock(zip, rustls, quinn-proto). Fixing only (1) would leave this PR unmergeable. Fixing them in the dependabot PRs instead is a deadlock, since those can't pass CI without (1).Commits
fix(llm): both call sites go through one privatefetch_updatehelper with a single#[allow(deprecated)]. Orderings and closures are unchanged. The compiler's suggestedtry_updateis not used: it is unstable on the 1.88 MSRV (E0658, reproduced locally), so it would just move the failure to themsrvjob.fix(audio): removes an unneededreturnin thecfg(windows)branch ofatomic::replace_file. CI's clippy runs on Linux and never compiles that block, so this only affects a Windows-local-D warningsrun. Behavior is unchanged.fix(deps)rustls + quinn-proto: lockfile only. rustls 0.23.45 → 0.23.46 (RUSTSEC-2026-0346/0347/0348/0349); quinn-proto 0.11.16 → 0.11.19 (RUSTSEC-2026-0338 through 0342). quinn-proto is only reqwest's optionalhttp3dependency and isn't compiled, butcargo auditreads every lockfile entry.fix(deps)zip 9: zip 8.6.0 → 9.0.5 (RUSTSEC-2026-0367/0368/0369). Those advisories concernextract(), which BookForge never calls, so they weren't reachable here. zip 9.0.5 declaresrust-version = "1.88"; its newnixdependency is macOS/BSD-only. Supersedes dependabot build(deps): bump zip from 8.6.0 to 9.0.0 #152.fix(deps)rustls-webpki + webpki-roots (added Oct 21): lockfile only. rustls-webpki 0.103.15 → 0.103.16 (RUSTSEC-2026-0382, distrusted intermediates could be accepted) and webpki-roots 1.0.8 → 1.0.10 (RUSTSEC-2026-0381, distrusted emSign intermediates). Both advisories were published on Oct 19–20, after this PR's audit first passed, and the stacked fix(validation): stop untranslated prose hiding behind reference context #160 failed the audit on them. Both releases are within the 1.88 MSRV;cargo audit --deny warningspasses again.zip 9: what changed in behavior
ZipFile::name()andZipArchive::file_names()now returnZipResult<Cow<str>>, so 6 call sites inbookforge-epuband one test changed. zip 9 decodes names lazily: UTF-8 first, then CP437, which maps every byte. So no name that 8.6 accepted is now rejected. The only difference: an entry flagged UTF-8 that contains invalid bytes decodes as CP437 instead of lossy UTF-8; such an entry is invalid EPUB either way.validate.rskeeps its existing skip-unreadable-entry behavior. New test: a non-ASCII entry name (capítulo-東京.xhtml) resolves throughinspect,readandrebuild.InvalidDataI/O error with no entry name.ArchiveReadBudget::read_entrynow re-raisesInvalidDataread errors asEPUB decompression failed for '<entry>': …, matching its other limit errors and the module's promise to name failing entries. Genuine I/O errors are still passed through unchanged. Three tests changed:ArchiveReadBudget, so the read-time running total is still exercised.No CHANGELOG entry, consistent with #145/#146/#148; the zip-bomb change is internal hardening with no user-facing option. Happy to add one if you'd like it recorded.
Validation
Run on Windows (GNU) with CI's exact compiler, rustc 1.99.1, and
RUSTFLAGS="-D warnings", following the steps ofscripts/verify.sh:cargo audit --deny warnings(the required check's command): 0 advisories, exit 0cargo clippy --workspace --all-targets --all-features --locked -- -D warnings: passcargo +1.88.0 check --workspace --all-targets --locked(MSRV): passcargo fmt --all --check,git diff --check,scripts/validate-release-security.sh,cargo check -p bookforge-cli --no-default-features, dashboardruntime.test.cjs: passcargo test --workspace --locked: 1,426 passed, 1 failed, 9 ignored;--examples: 13 passed;bookforge-epubalone: 165 passed. The one failure wascli_pause_during_inflight_qa_request_parks_before_more_finalize_workwithAccess is denied. (os error 5), a Windows file-sharing race between the paused and resumed processes, unrelated to zip. It passed in both earlier gate runs of this branch, 8/8 run alone, and in two full runs of thelifecyclebinary (56/56 each).clippy,test,test (windows-msvc),msrv,fmt,corpus (small)and CodeQL on GitHub; only the audit failed.Known flaky test, unrelated to this PR.
batch::tests::persistent_decode_error_bisects_an_oversized_batch_after_retryfails intermittently on Windows with request counts[2, 2]instead of[2, 2, 1, 1], and can hang, becauseserver.awaithas no timeout. Batch execution uses the limiter touched in the first commit, so I compared under identical conditions (same toolchain, flags and machine):batch::testsmodule ×10main(before)These are small samples. They show no regression, not an improvement. The flake needs its own fix.
After merge
Rebase the remaining dependabot PRs (#153, #155, #156, #157, #158). #152 is superseded by this PR, and dependabot should close it once
mainhas zip 9.🤖 Generated with Claude Code