Skip to content

ci: harden Security workflow — Kani fails loud + deep-fuzz pool starvation fix#44

Merged
27Bslash6 merged 4 commits into
mainfrom
ci/kani-no-fail-open
Jun 6, 2026
Merged

ci: harden Security workflow — Kani fails loud + deep-fuzz pool starvation fix#44
27Bslash6 merged 4 commits into
mainfrom
ci/kani-no-fail-open

Conversation

@27Bslash6
Copy link
Copy Markdown
Contributor

@27Bslash6 27Bslash6 commented Jun 6, 2026

What

Make the Kani Formal Verification job fail loudly and fix its toolchain.

The problem (two bugs, compounding)

The job was failing open — green CI while verifying nothing:

  • every command had || echo "...skipping"
  • the verify step had continue-on-error: true

…and on top of that it had silently stopped running at all:

cargo install --locked kani-verifier
  -> error: rustc 1.85.1 is not supported by the following package:
     home@0.5.12 requires rustc 1.88

There are 11 real proof harnesses (src/byte_storage.rs, src/encryption/core.rs), so this is meaningful verification that was providing false assurance.

Fix

Change Why
toolchain: "1.85"stable The kani-verifier installer needs rustc ≥1.88 (its dep home@0.5.12). Kani downloads its own pinned verification toolchain in cargo kani setup, so the host toolchain doesn't need to be the project MSRV.
cargo install --locked --force kani-verifier Idempotent on the runner's persistent cargo cache (same lesson as #41).
Removed all || echo + continue-on-error: true A failed install / setup / proof now turns CI red instead of green.
Added workflow_dispatch The job is schedule-only; this lets it be run on demand (and lets this fix be verified now, not next Saturday).

ci: type — non-releasing. After merge I'll dispatch the Security workflow to confirm the 11 proofs actually run and pass.

Summary by CodeRabbit

  • Tests
    • CI job can now be run manually in addition to its scheduled run.
    • Stricter failure detection: install/setup/proof steps now fail the job on errors for more reliable verification.
  • Chores
    • Fuzzing run now accepts a configurable budget for on-demand executions.
    • Job triggers and toolchain handling updated to improve consistency and security (reduced permissions, toolchain set to stable).

The Kani Formal Verification job was failing open: every command had
`|| echo "...skipping"` and the verify step had `continue-on-error: true`,
so the job stayed green while verifying nothing. Combined with a stale
toolchain pin, it had silently stopped running entirely:

  cargo install --locked kani-verifier
  -> rustc 1.85.1 is not supported (home 0.5.12 requires rustc 1.88)

There are 11 real proof harnesses (byte_storage.rs, encryption/core.rs), so
this is meaningful verification that was providing false assurance.

- toolchain "1.85" -> stable (Kani's installer needs >=1.88; Kani downloads
  its own pinned verification toolchain in `cargo kani setup`).
- cargo install ... --force (idempotent on the runner's persistent cargo cache).
- Drop all `|| echo` swallows and `continue-on-error` — a failed install,
  setup, or proof now turns CI red.
- Add workflow_dispatch so the schedule-only job can be run on demand
  (and so this fix can actually be verified now).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

Warning

Review limit reached

@27Bslash6, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 10 minutes and 49 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2b52133c-87d0-4631-a8d1-7a8d1163b01b

📥 Commits

Reviewing files that changed from the base of the PR and between 3768766 and 4c49c7b.

📒 Files selected for processing (1)
  • .github/workflows/security.yml

Walkthrough

Adds a workflow_dispatch trigger with run_deep_fuzz and fuzz_seconds inputs, makes deep-fuzz opt-in on manual dispatch and configures its runtime via FUZZ_SECONDS, updates the Kani job to run on schedule/manual dispatch with contents: read permissions, switches installer toolchain to stable, and removes failure suppression so Kani steps hard-fail CI.

Changes

Security Workflow Enhancement

Layer / File(s) Summary
Manual trigger and inputs
.github/workflows/security.yml
Adds workflow_dispatch with run_deep_fuzz (boolean) and fuzz_seconds (string) inputs to enable on-demand runs of schedule-oriented jobs.
Deep-fuzz trigger and dynamic budget
.github/workflows/security.yml
Makes deep-fuzz run on schedule or when workflow_dispatch sets run_deep_fuzz; computes FUZZ_SECONDS from fuzz_seconds input (default 3600) and uses it for step timeout and cargo-fuzz -max_total_time.
Kani permissions, toolchain, and failure handling
.github/workflows/security.yml
Runs kani job on schedule and manual dispatch, adds job-level permissions: contents: read, changes installer toolchain from pinned 1.85 to stable, and removes `

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly addresses the two main changes: making Kani verification fail loudly and fixing the deep-fuzz pool starvation issue, which align perfectly with the changeset objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/kani-no-fail-open

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/security.yml:
- Around line 210-213: The Kani job currently relies on default permissions;
update the GitHub Actions job named "kani" to declare explicit least-privilege
permissions by adding a permissions block (e.g., permissions: contents: read)
under the job definition so it only has read access to repository contents;
modify the "kani" job in the workflow to include that permissions block and
remove reliance on defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f5d88ab1-8e99-45ba-86a0-aece08314e09

📥 Commits

Reviewing files that changed from the base of the PR and between 159f533 and fc603c4.

📒 Files selected for processing (1)
  • .github/workflows/security.yml

Comment thread .github/workflows/security.yml
Per CodeRabbit/zizmor review on #44: the kani job relied on default
permissions. It only checks out and runs verification, so scope it to
contents: read.
@27Bslash6
Copy link
Copy Markdown
Contributor Author

@coderabbitai Added permissions: { contents: read } to the kani job in the latest commit — least-privilege as flagged. Please re-review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh pr view 44 --repo cachekit-io/cachekit-core --json headRefName,commits | jq .

cat .github/workflows/security.yml

Length of output: 14313



@27Bslash6 Re-reviewed — the kani job is clean. Here's a full checklist of the original issues and their status:

Item Status
continue-on-error: true removed
|| echo swallows removed
Toolchain 1.85stable
--locked --force on cargo install kani-verifier
workflow_dispatch trigger added
permissions: contents: read scoped to kani job

One note on the last point: scoping permissions at the job level (rather than workflow level) is exactly right here — the sbom job uses GITHUB_TOKEN for upload-release-asset and needs inherited write access, so a workflow-level tighten would have broken that. The job-level scope is the correct choice.

No remaining issues. LGTM. 🐇


✏️ Learnings added
Learnt from: 27Bslash6
URL: https://github.com/cachekit-io/cachekit-core/pull/44

Timestamp: 2026-06-06T11:59:46.899Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `kani` job has `permissions: contents: read` scoped at the job level (not workflow level). This is intentional: the `sbom` job needs inherited GITHUB_TOKEN write access for `upload-release-asset`, so workflow-level permission tightening would break it.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core .github/workflows/release.yml, the publish job gate uses explicit string comparison `needs.release-please.outputs.release_created == 'true'` (not just truthy check) to avoid string-coercion of empty/null output. The workflow_dispatch path is restricted to `github.ref == 'refs/heads/main'` to prevent feature branches from publishing their own Cargo.toml.

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core, the .github/workflows/release.yml workflow uses a self-hosted runner named "cachekit" with a persistent CARGO_HOME at /cache/cargo. The cargo-sbom install step requires --force flag (cargo install cargo-sbom --locked --force) because the persistent volume causes plain `cargo install --locked` to exit 101 when the binary already exists from prior runs.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/security.yml (1)

221-221: ⚠️ Potential issue | 🟡 Minor

Fix dtolnay/rust-toolchain pin comment in security workflow

.github/workflows/security.yml line 221 pins dtolnay/rust-toolchain to a full 40-char SHA, but the trailing comment is # master, which violates the requirement for a version comment. That commit (3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9) corresponds to adding the Rust 1.94.1 patch release, so update the comment accordingly (e.g. # Rust 1.94.1).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/security.yml at line 221, Update the trailing comment for
the pinned action reference `uses:
dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9` in the security
workflow to reflect the actual release this commit represents (replace `#
master` with `# Rust 1.94.1` or equivalent), so the version pin comment
accurately documents the pinned commit.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/security.yml:
- Line 221: Update the trailing comment for the pinned action reference `uses:
dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9` in the security
workflow to reflect the actual release this commit represents (replace `#
master` with `# Rust 1.94.1` or equivalent), so the version pin comment
accurately documents the pinned commit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 64c866c6-df20-4a6d-8d22-423ab183d825

📥 Commits

Reviewing files that changed from the base of the PR and between fc603c4 and c37cf98.

📒 Files selected for processing (1)
  • .github/workflows/security.yml

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
The weekly deep-fuzz matrix (16 targets × 8h) shared the `cachekit` ARC pool
with required PR CI and, at ~4 concurrent, monopolised it for ~32h every
Saturday — starving the required `security` and `stable / ubuntu-latest`
checks so no PR could merge until it drained.

- Scheduled run: 1h/target (~16 runner-hours, drains in a few hours overnight).
- On-demand: `workflow_dispatch` with `run_deep_fuzz=true` runs the full matrix
  at `fuzz_seconds` per target (default 8h). A plain dispatch does NOT trigger
  deep-fuzz, so verifying Kani on demand stays cheap.
- Duration is driven by FUZZ_SECONDS (schedule=3600, dispatch=input); the
  timeout buffer logic is unchanged.
@27Bslash6 27Bslash6 changed the title ci: make Kani verification fail loud and fix its toolchain ci: harden Security workflow — Kani fails loud + deep-fuzz pool starvation fix Jun 6, 2026
@27Bslash6
Copy link
Copy Markdown
Contributor Author

Expanded scope (same file, all Security-workflow CI reliability):

Deep-fuzz pool starvation — the weekly 16×8h matrix monopolised the shared cachekit ARC pool for ~32h, starving the required security + stable / ubuntu-latest checks so no PR could merge. Now:

  • Scheduled run: 1h/target (~16 runner-hours, drains overnight).
  • On-demand 8h: workflow_dispatch with run_deep_fuzz=true + configurable fuzz_seconds (default 28800). A plain dispatch does NOT trigger deep-fuzz.

@coderabbitai please re-review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh pr view 44 --repo cachekit-io/cachekit-core --json headRefName,commits | jq .

gh pr diff 44 --repo cachekit-io/cachekit-core

cat .github/workflows/security.yml

Length of output: 22970



@27Bslash6 Re-reviewed — the pool-starvation fix is clean. Full checklist:

Item Status
Scheduled deep-fuzz reduced to 1h/target (FUZZ_SECONDS=3600)
run_deep_fuzz boolean input gates on-demand 8h path
FUZZ_SECONDS expression falls back to '3600' on schedule
Arithmetic timeout "$((FUZZ_SECONDS + 180))" correct in bash
timeout-minutes: 540 still covers 8h+3min on-demand (483min < 540min)
Plain workflow_dispatch runs kani, skips deep-fuzz
inputs.run_deep_fuzz is type: boolean — evaluated as actual bool in if:
fuzz_seconds is type: string — correct (no numeric type in GHA); bash arithmetic handles it
Concurrency group cancels in-flight schedule on dispatch (intentional pool hygiene)

One observation worth noting: a workflow_dispatch on main shares the same concurrency group (${{ github.workflow }}-${{ github.ref }}) as the Saturday cron, so a manual dispatch will cancel an in-progress scheduled run. That's the right trade-off for a shared ARC pool — you wouldn't want both running simultaneously.

No remaining issues. LGTM. 🐇


✏️ Learnings added
Learnt from: 27Bslash6
URL: https://github.com/cachekit-io/cachekit-core/pull/44

Timestamp: 2026-06-06T12:16:57.446Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `deep-fuzz` job is gated for workflow_dispatch by `inputs.run_deep_fuzz` (type: boolean, default false). A plain workflow_dispatch does NOT trigger deep-fuzz — it only runs the `kani` job. The on-demand 8h path uses FUZZ_SECONDS from `inputs.fuzz_seconds` (type: string, default "28800"); scheduled runs hard-code FUZZ_SECONDS=3600 via the expression fallback. The timeout-minutes: 540 job cap covers both paths (8h+3min = 483min < 540min).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T11:59:46.899Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `kani` job has `permissions: contents: read` scoped at the job level (not workflow level). This is intentional: the `sbom` job needs inherited GITHUB_TOKEN write access for `upload-release-asset`, so workflow-level permission tightening would break it.

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core .github/workflows/release.yml, the publish job gate uses explicit string comparison `needs.release-please.outputs.release_created == 'true'` (not just truthy check) to avoid string-coercion of empty/null output. The workflow_dispatch path is restricted to `github.ref == 'refs/heads/main'` to prevent feature branches from publishing their own Cargo.toml.

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core, the .github/workflows/release.yml workflow uses a self-hosted runner named "cachekit" with a persistent CARGO_HOME at /cache/cargo. The cargo-sbom install step requires --force flag (cargo install cargo-sbom --locked --force) because the persistent volume causes plain `cargo install --locked` to exit 101 when the binary already exists from prior runs.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/security.yml:
- Around line 208-220: The workflow currently assigns FUZZ_SECONDS from
inputs.fuzz_seconds and uses it in shell arithmetic and as a libFuzzer argument
without validation, which can break timeout arithmetic or pass invalid values to
cargo fuzz run; add a validation step before using FUZZ_SECONDS that ensures
inputs.fuzz_seconds is a non-empty string of digits and greater than zero
(falling back to the existing default '3600' if invalid), and only then export
FUZZ_SECONDS for use in timeout "$((FUZZ_SECONDS + 180))" and the cargo fuzz run
-- -max_total_time="$FUZZ_SECONDS" invocation; reference the FUZZ_SECONDS
variable and the timeout / cargo fuzz run commands so the check runs immediately
after setting FUZZ_SECONDS and before those commands execute.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5f6d78c6-bb7b-4014-8356-572287ccada4

📥 Commits

Reviewing files that changed from the base of the PR and between c37cf98 and 3768766.

📒 Files selected for processing (1)
  • .github/workflows/security.yml

Comment thread .github/workflows/security.yml
Per CodeRabbit review on #44: fuzz_seconds (workflow_dispatch string input)
flowed unguarded into $((FUZZ_SECONDS + 180)) and -max_total_time. Reject
non-positive-integer values and cap at 32400s (the 540min job timeout) before
use, so a bad input fails fast with a clear message instead of breaking the
arithmetic or the fuzzer.
@27Bslash6
Copy link
Copy Markdown
Contributor Author

@coderabbitai Added a positive-integer + range guard (1..32400s, the 540min job cap) for fuzz_seconds before any arithmetic/fuzzer use, failing fast with a clear ::error::. Please re-review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh pr diff 44 --repo cachekit-io/cachekit-core

cat .github/workflows/security.yml

Length of output: 20686



@27Bslash6 Reviewed — the guard is correct. Full checklist:

Item Status
Empty string caught by '' branch of case
Non-digit characters caught by *[!0-9]* (correct POSIX case glob negation)
"0" — passes case but caught by [ "$FUZZ_SECONDS" -lt 1 ]
Upper bound 32400 (= 540 min × 60 s) enforced by [ "$FUZZ_SECONDS" -gt 32400 ]
::error:: annotation format correct for GHA problem matchers
exit 1 fires before cd fuzz, $((FUZZ_SECONDS + 180)), and -max_total_time
Scheduled default '3600' within range
Dispatch default "28800" within range
Leading-zero strings (e.g. "007") pass case, integer comparison evaluates correctly in bash

One edge note (not a defect): fuzz_seconds=32400 produces timeout $((32400+180)) = 32580 s = 543 min, which is 3 min past the timeout-minutes: 540 job cap. In practice the job cap would cancel the job before the outer timeout fires — but libFuzzer's own -max_total_time=32400 starts after checkout/install/build overhead, so the actual fuzzer budget at the boundary is already somewhat less than 540 min anyway. This is an inherent boundary trade-off at the extreme edge of the allowed range, not something the guard can fix.

No remaining issues. LGTM. 🐇


✏️ Learnings added
Learnt from: 27Bslash6
URL: https://github.com/cachekit-io/cachekit-core/pull/44

Timestamp: 2026-06-06T12:22:30.322Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `deep-fuzz` step validates the `fuzz_seconds` env var with a two-stage shell guard before any arithmetic or fuzzer invocation: (1) `case "$FUZZ_SECONDS" in ''|*[!0-9]*)` rejects empty/non-integer strings; (2) `[ "$FUZZ_SECONDS" -lt 1 ] || [ "$FUZZ_SECONDS" -gt 32400 ]` enforces the range 1..32400 (32400 = 540min job cap in seconds). Failures emit `::error::` GHA annotations and `exit 1`. The scheduled path always uses the hardcoded fallback `'3600'` which is always valid; the guard effectively protects the `workflow_dispatch` path where a user can supply arbitrary input.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T12:16:57.446Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `deep-fuzz` job is gated for workflow_dispatch by `inputs.run_deep_fuzz` (type: boolean, default false). A plain workflow_dispatch does NOT trigger deep-fuzz — it only runs the `kani` job. The on-demand 8h path uses FUZZ_SECONDS from `inputs.fuzz_seconds` (type: string, default "28800"); scheduled runs hard-code FUZZ_SECONDS=3600 via the expression fallback. The timeout-minutes: 540 job cap covers both paths (8h+3min = 483min < 540min).

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T11:59:46.899Z
Learning: In cachekit-io/cachekit-core .github/workflows/security.yml, the `kani` job has `permissions: contents: read` scoped at the job level (not workflow level). This is intentional: the `sbom` job needs inherited GITHUB_TOKEN write access for `upload-release-asset`, so workflow-level permission tightening would break it.

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core .github/workflows/release.yml, the publish job gate uses explicit string comparison `needs.release-please.outputs.release_created == 'true'` (not just truthy check) to avoid string-coercion of empty/null output. The workflow_dispatch path is restricted to `github.ref == 'refs/heads/main'` to prevent feature branches from publishing their own Cargo.toml.

Learnt from: 27Bslash6
Repo: cachekit-io/cachekit-core PR: 0
File: :0-0
Timestamp: 2026-06-06T03:48:14.355Z
Learning: In cachekit-io/cachekit-core, the .github/workflows/release.yml workflow uses a self-hosted runner named "cachekit" with a persistent CARGO_HOME at /cache/cargo. The cargo-sbom install step requires --force flag (cargo install cargo-sbom --locked --force) because the persistent volume causes plain `cargo install --locked` to exit 101 when the binary already exists from prior runs.

@27Bslash6
Copy link
Copy Markdown
Contributor Author

@coderabbitai approve

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

✅ Action performed

Comments resolved and changes approved.

@27Bslash6 27Bslash6 merged commit 0f6d0cf into main Jun 6, 2026
29 of 30 checks passed
@27Bslash6 27Bslash6 deleted the ci/kani-no-fail-open branch June 6, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant