The gap
#838's acceptance criterion 4 is in two halves:
Cargo.lock is committed and CI builds use --locked, so a future
incompatible bump fails at the lockfile rather than resolving differently in
CI than locally.
PR #840 satisfies the first half — the lockfile is committed and updated. The
second half is not satisfied and was not satisfiable in that PR.
Measured, 2026-09-22, on origin/main
No cargo invocation in any workflow passes --locked. Zero hits:
$ command grep -rn 'cargo \(check\|clippy\|test\|build\|fmt\|doc\)' .github/workflows/*.yml \
| command grep -c -- '--locked'
0
The unlocked invocations that matter are:
| File:line |
Command |
.github/workflows/ci.yml:52 |
cargo check --workspace --all-targets |
.github/workflows/ci.yml:55 |
cargo clippy --workspace --all-targets -- -D warnings |
.github/workflows/ci.yml:95 |
cargo test --workspace --all-targets |
.github/workflows/ci.yml:98 |
cargo test --workspace --doc |
.github/workflows/rust.yml:35 |
cargo check --workspace |
.github/workflows/rust.yml:47 |
cargo test --workspace |
.github/workflows/rust.yml:72 |
cargo clippy --workspace -- -D warnings |
.github/workflows/rust.yml:92,98,119 |
cargo check/clippy/test --all-targets |
.github/workflows/quality.yml:122 |
cargo doc --workspace --no-deps --document-private-items |
Why it matters
Without --locked, cargo is free to re-resolve and silently write a
different Cargo.lock in CI than the one committed. Two consequences:
- A dependency change that should fail loudly at the lockfile instead
resolves to something else in CI, so CI and local disagree about what was
actually built — and the disagreement is invisible.
- The committed lockfile stops being evidence of anything. It is checked in,
but nothing verifies CI honoured it.
This is the same shape as the recurring guard/consumer mismatch: the lockfile
is the demand, but no CI step consumes it as a constraint.
Acceptance criteria
- Every cargo invocation in
ci.yml, rust.yml and quality.yml that builds,
checks, lints, tests or documents workspace code passes --locked.
(cargo fmt takes no such flag and is out of scope.)
- A mutant proves the guard has teeth: on a branch, hand-edit
Cargo.lock so
it disagrees with Cargo.toml (e.g. bump a version string in the lock only)
and confirm CI fails with cargo's
the lock file ... needs to be updated but --locked was passed error —
not a compile error, and not a silent re-resolve. Reverting restores
green.
- The failure is legible: the job that fails names the lockfile in its output,
so the next person reads "lockfile out of date" rather than a downstream
symptom.
Blocked on
This needs edits to .github/workflows/*, which requires the workflow OAuth
scope. The current session token carries only
admin:public_key, gist, read:org, repo, so it cannot push workflow changes.
Unblocked by the owner re-authenticating with workflow in the scope set.
Split out of #838 rather than left silently unticked. Related: #840.
The gap
#838's acceptance criterion 4 is in two halves:
PR #840 satisfies the first half — the lockfile is committed and updated. The
second half is not satisfied and was not satisfiable in that PR.
Measured, 2026-09-22, on
origin/mainNo cargo invocation in any workflow passes
--locked. Zero hits:The unlocked invocations that matter are:
.github/workflows/ci.yml:52cargo check --workspace --all-targets.github/workflows/ci.yml:55cargo clippy --workspace --all-targets -- -D warnings.github/workflows/ci.yml:95cargo test --workspace --all-targets.github/workflows/ci.yml:98cargo test --workspace --doc.github/workflows/rust.yml:35cargo check --workspace.github/workflows/rust.yml:47cargo test --workspace.github/workflows/rust.yml:72cargo clippy --workspace -- -D warnings.github/workflows/rust.yml:92,98,119cargo check/clippy/test --all-targets.github/workflows/quality.yml:122cargo doc --workspace --no-deps --document-private-itemsWhy it matters
Without
--locked, cargo is free to re-resolve and silently write adifferent
Cargo.lockin CI than the one committed. Two consequences:resolves to something else in CI, so CI and local disagree about what was
actually built — and the disagreement is invisible.
but nothing verifies CI honoured it.
This is the same shape as the recurring guard/consumer mismatch: the lockfile
is the demand, but no CI step consumes it as a constraint.
Acceptance criteria
ci.yml,rust.ymlandquality.ymlthat builds,checks, lints, tests or documents workspace code passes
--locked.(
cargo fmttakes no such flag and is out of scope.)Cargo.locksoit disagrees with
Cargo.toml(e.g. bump a version string in the lock only)and confirm CI fails with cargo's
the lock file ... needs to be updated but --locked was passederror —not a compile error, and not a silent re-resolve. Reverting restores
green.
so the next person reads "lockfile out of date" rather than a downstream
symptom.
Blocked on
This needs edits to
.github/workflows/*, which requires theworkflowOAuthscope. The current session token carries only
admin:public_key, gist, read:org, repo, so it cannot push workflow changes.Unblocked by the owner re-authenticating with
workflowin the scope set.Split out of #838 rather than left silently unticked. Related: #840.