ci: attestation-check verifies what users install, and its schedule cannot die silently (LAB-1036) - #65
Conversation
…e (LAB-1036) Gap 1: after verifying the latest GitHub release's crate, compare it to crates.io max_stable_version — the version 'cargo add' actually resolves. A hand-published version, a prerelease-skipped release, or a yank now goes red instead of leaving the job green while users install an unverified crate. The release→publish window (release.yml tags before cargo publish) is tolerated only on a positive observation: verified side newer AND a release.yml run observably queued/in progress. Gap 2: assert schedule liveness in-job. GitHub silently disables schedule: triggers in public repos after ~60 days of repo inactivity; fail at >50 days stale so the weekly cron goes red (and files its tracking issue) before the schedule dies. 50, not 55: a margin narrower than the 7-day cron period can be jumped over entirely.
…ed everywhere Panel (bug-hunter, security, craftsman, catchphrase) findings applied: - DELETE the release-window tolerance branch: unreachable for its stated purpose (during the window the crate isn't on crates.io, so the job is already red at the download step), and itself a fail-open — release.yml runs on every push to main, so an unrelated in-flight run would green-light a dead publish or yanked version. Mismatch now fails unconditionally. - versions array: explicit Array.isArray fail-closed instead of '|| []' silently degrading yank detection. - liveness threshold 50 → 43: margin must fit two weekly cron attempts so one delayed/dropped scheduled run still leaves a red before the ~60-day auto-disable. - liveness comparison NaN-proofed: !(x <= 43) fails closed on unparsable pushed_at. - distinct dedupe marker/title/body for liveness failures so an open staleness issue can't swallow a later real attestation break. - crates.io UA hoisted to job-level env (was duplicated verbatim).
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 26 seconds Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
Comment |
This comment has been minimized.
This comment has been minimized.
|
@coderabbitai review |
✅ Action performedReview finished.
|
…rate-object shape (Kody review) - wrap the fetch + JSON parse in try/catch: a DNS failure, connection reset, or non-JSON 200 body now fails with a named message instead of a raw unhandled-rejection trace (still red either way). - guard data.crate before dereferencing max_stable_version, matching the existing versions-array shape guard: an error-shaped 200 fails with a message, not a TypeError.
Kody Review CompleteGreat news! 🎉 Keep up the excellent work! 🚀 Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
|
@kody start-review |
Summary
This PR strengthens the
attestation-checkworkflow to close two silent failure gaps identified in LAB-1036.1. Verify what users actually install
Previously the workflow only verified that the latest GitHub release's
.cratewas authentic (valid SLSA provenance and CycloneDX SBOM). It did not confirm that this verified version is the onecargo addresolves by default. A new step, "Check crates.io serves the verified version", queries the crates.io API and fails the job when:versionsarray) — fails closed rather than silently skipping yank detection.max_stable_versiondoes not match the verified version — meaning users installing viacargo addwould get a version this job never verified (e.g., hand-published, prerelease-skipped, or a publish that died after tagging).2. Prevent the schedule from dying silently
GitHub auto-disables
schedule:triggers in public repos after ~60 days of inactivity, which would turn this job's failure mode into "not running at all." A new "Assert schedule liveness" step fails the job when the repository has had no push activity for more than 43 days — giving a red run and tracking issue before the schedule goes dark. The 43-day threshold leaves margin for at least two weekly cron attempts. Malformed push timestamps fail closed.3. Per-failure-class issue deduplication
The "Open issue on failure" step now distinguishes two mutually exclusive failure classes:
This prevents an open staleness issue from swallowing a later real attestation break for the same tag. Issue titles and bodies are tailored to each failure class, and the troubleshooting guidance is expanded to cover the new
max_stable_versionand push-activity checks.4. Shared crates.io User-Agent
The descriptive crates.io User-Agent string (required because crates.io returns 403 to generic user agents) is consolidated into a job-level
CRATES_IO_UAenvironment variable, shared across all crates.io calls in the job.Summary
This PR hardens the
attestation-checkCI workflow to make the crates.io verification step more resilient and fail loudly rather than silently.Changes
Network-level error handling
fetchcall to the crates.io API in atry/catchblock so that network-level failures (DNS resolution, connection resets) or non-JSON response bodies now fail with a descriptive error message instead of producing a raw unhandled-rejection stack trace.Response shape validation
crateobject in the API response. An error-shaped200response missing thecrateobject now fails with a clear message instead of throwing aTypeErrorfurther down the pipeline.Purpose
These changes ensure the attestation check reliably verifies what users actually install from crates.io. By failing closed with clear diagnostics on any network failure or unexpected response shape, the workflow's scheduled runs cannot pass or die silently, preserving the integrity of the yank-status and install-drift detection.