Pinning CI meant a future Rust release could break the build without
anyone noticing until the pin moved. This job tracks latest stable and
runs the test suite and clippy, so that breakage is visible early.
Marked `continue-on-error`, so it reports rather than gates: a new
clippy lint landing in stable should not fail a pull request that did
not cause it. The pinned `test` job remains the gate.
Note that GitHub renders a `continue-on-error` job as passing with an
annotation rather than as failed. If it should be more visible, make it
a required check and drop the flag.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dev shell tracked `stable.latest` and CI used `@stable`, so nothing
pinned a version and nothing declared a floor. A consumer on an older
toolchain hit a confusing error deep in a dependency rather than cargo
saying the version was too old, and a new stable release could turn a
lint into an unrelated red build.
- `rust-version = "1.88"` in Cargo.toml. The floor comes from the
dependency graph, not this crate's code: reqwest pulls in url -> idna
-> idna_adapter -> icu_*, and the icu crates require 1.88. Verified by
running the full suite against 1.88, not inferred.
- flake.nix pins the dev toolchain to 1.99.1 and adds an `msrv` devShell,
so the floor can be rechecked with
`nix develop .#msrv --command cargo test`.
- CI pins the main job to the same 1.99.1 and adds a job building on
1.88. Lint and format stay on the pinned toolchain only, since their
output varies by release.
Note the tradeoff: with CI pinned, a future stable that breaks the build
will not be noticed until the pin moves. Worth adding a non-blocking
`stable` job if that matters.
CLAUDE.md records the three places that must agree when either version
moves, and how to recheck the floor after a dependency bump.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Covers Clients, Invoices, Quotes, Credits, Payments, Products, Expenses,
Projects, Tasks, and Vendors, each with list, list_all, get, create,
update, and delete, generated by the resource_methods! macro.
Every model carries a #[serde(flatten)] extra map so fields the API
returns but the crate does not model survive a get/update round-trip
instead of being silently dropped.
Includes a Nix dev shell (Rust via rust-overlay), a GitHub Actions CI
workflow running build/test/fmt/clippy, and round-trip tests for the
extra-preservation invariant.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>