Skip to content

Add kani-slow feature gate and lower CI parallelism to 2 - #2751

Open
strawgate wants to merge 6 commits into
mainfrom
fix/kani-ci-timeouts
Open

strawgate wants to merge 6 commits into
mainfrom
fix/kani-ci-timeouts

Conversation

@strawgate

@strawgate strawgate commented May 1, 2026 •

Copy link
Copy Markdown
Owner

Reduce Kani CI resource usage to prevent OOM on 16 GB runners by reducing parallel jobs, tightening proof bounds, and gating expensive proofs behind a kani-slow feature. The kani-slow proofs (~15 proofs, >30s each) run only on push-to-main and ci:full PRs, keeping PR CI fast at ~5 min wall-clock for the core shard.

  • CI: All shards now use --jobs 2 (down from 3–4) since CBMC solver processes consume 3–5 GB each and --jobs 3+ causes OOM/preemption on 16 GB runners
  • Added kani-slow feature flag to ffwd-core and ffwd-kani crates, gating ~15 expensive proofs behind --features kani-slow; conditional in CI for push-to-main and ci:full label
  • verify_json_escape_bytes_vs_oracle: Array bounded 16 → 8 bytes, unwind 100 → 50
  • verify_hex_decode_rejects_wrong_length: Vec replaced with [b'a'; 34] stack array, unwind 36 (Vec caused 800s+ of CBMC allocator modeling)
  • verify_encode_bytes_field_content_compositional: Data bounded 8 → 4 bytes, unwind 12
  • verify_parse_int_fast_vs_oracle: Bounded 20 → 10 bytes, unwind 22 → 12; removed 500s+ roundtrip check that modeled allocator; split into two kani-slow proofs for mid-range (11-17 bytes) and overflow boundary (18-20 bytes, constrained to digits)
  • merge_child_send_result in sink.rs: Duration values bounded to ≤30,000 ms to avoid 500s+ of symbolic u64/Duration arithmetic
  • Added dev-docs/references/kani-verification.md section on performance best practices (avoid Vec/String in proofs, bound arithmetic, constrain inputs for targeted proofs)

Note

Add kani-slow feature gate and reduce CI parallelism to 2 jobs for Kani proofs

  • Introduces a kani-slow feature flag in ffwd-core and ffwd-kani to gate expensive Kani proofs, which are now only run on push to main or PRs labeled ci:full; default PRs run fast proofs only.
  • Gates ~15 heavy proofs across cri.rs, framer.rs, json_scanner.rs, otlp.rs, scan_config.rs, structural.rs, structural_iter.rs, and bytes.rs behind #[cfg(feature = "kani-slow")].
  • Reduces --jobs from 3–4 to 2 across all Kani CI shards to reduce memory pressure, raises kani-core timeout from 90 to 120 minutes, and lowers kani-arrow timeout from 90 to 60 minutes.
  • Tightens several proof bounds (e.g. json escape oracle input reduced from 16→8 bytes, verify_encode_bytes_field_content_compositional data length bounded to ≤4) to keep fast proofs tractable.
  • Adds a new Kani performance best-practices section to kani-verification.md.

Macroscope summarized c92fc41.

All Kani CI shards have been failing consistently (0/50 recent CI runs
passed). Root cause: CBMC solver processes consume 3-5 GB each, and at
--jobs 3-4 on 16 GB runners, peak memory exceeds available RAM causing:
- Runner preemption ("runner shutdown signal" after 2-3 minutes)
- OOM kills mid-verification
- Core shard timeout at 90 min (too tight for 145 proofs)

Changes:
- Reduce --jobs from 3/4 to 2 across all Kani shards (peak ~10 GB)
- Increase kani-core timeout: 90 → 120 min (145 proofs with unwind ≤100)
- Decrease kani-arrow timeout: 90 → 60 min (24 proofs, finishes in ~5 min)
- Update documentation comments with accurate proof counts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 1, 2026 03:33
@strawgate strawgate added the bug Something isn't working label May 1, 2026
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label May 1, 2026
@pr-rocket

pr-rocket Bot commented May 1, 2026 •

Copy link
Copy Markdown

Looks ready to merge — no CI failures, open threads, or flagged issues.

👍 Well-structured Kani CI optimization: bounded proofs, gated slow proofs behind feature flag, reduced parallelism to prevent OOM — all intentional with documented trade-offs.

Last activity: No activity yet.


Configuration (5 of 12 enabled)

Auto-title · Auto-body · Auto-review · Auto-labels · Hide external comments

/rocket enable auto-pilot · /rocket enable <feature> · /rocket disable <feature>

@coderabbitai

coderabbitai Bot commented May 1, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

CI Kani configuration updated: kani-core timeout extended to 120m and now verifies ffwd-core plus ffwd-kani; kani-arrow timeout reduced to 60m; all shards’ Kani parallelism lowered to --jobs 2; --features kani-slow is enabled only for push-to-main or ci:full PRs. Numerous Kani proofs were constrained or feature-gated (kani-slow): JSON-escape oracle bound shortened to 8 bytes/unwind lowered; several OTLP, scan_config, structural, framer, json_scanner, and bytes proofs reduced in input size or unwind, converted to stack buffers, or gated; sink retry/delay values bounded. New docs add Kani verification guidance and CI proof-time rationale. A kani-slow Cargo feature was added to relevant crates.

Possibly related PRs


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Formal Verification Coverage ❌ Error All oracle proofs for compute_real_quotes and prefix_xor are gated behind kani-slow, leaving no fast oracle proofs in PR CI. Ungated at least one fast oracle or contract proof for compute_real_quotes and prefix_xor in structural.rs or bytes.rs.
Documentation Thoroughly Updated ⚠️ Warning PR missing ADR/design decision in DESIGN.md for kani-slow feature gating and OOM mitigation strategy. Add ADR section to DESIGN.md documenting kani-slow feature rationale, gating strategy, and performance techniques with references to kani-verification.md.
Maintainer Fitness ⚠️ Warning PR leaves three unresolved review comments flagging maintainer fitness gaps: oracle proofs gated behind kani-slow lack regular CI coverage; CI workflow lacks path-based auto-detection for slow-proof files; two long-running cri.rs proofs missing mandatory solver pinning. Address flagged comments: restore reduced-unwind oracle proofs to regular CI; add path-filter auto-detection to workflow for slow-proof files; add [kani::solver(kissat)] to long-running cri.rs proofs.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
High-Quality Rust Practices ✅ Passed PR contains only verification code within #[cfg(kani)] blocks, CI updates, and documentation. The kani-slow feature gates expensive proofs at compile-time only, not runtime behavior. No production code paths modified.
Crate Boundary And Dependency Integrity ✅ Passed PR introduces only cfg-gated Kani verification code and CI updates with no new external dependencies, crates, or std imports.

Review rate limit: 0/10 reviews remaining, refill in 55 minutes and 52 seconds.

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

@pr-rocket pr-rocket Bot changed the title fix(ci): reduce Kani --jobs to 2 to prevent OOM runner kills Reduce Kani --jobs to 2 to prevent OOM runner kills May 1, 2026
@pr-rocket pr-rocket Bot added chore performance Performance optimization labels May 1, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes May 1, 2026
@macroscopeapp

macroscopeapp Bot commented May 1, 2026 •

Copy link
Copy Markdown

Approvability

Verdict: Approved

CI-only changes that gate slow Kani verification proofs behind a feature flag and reduce parallelism to prevent OOM. No runtime code is affected - all modifications are in verification test modules and CI configuration.

You can customize Macroscope's approvability policy. Learn more.

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gitar has auto-approved this PR (configure)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adjusts the GitHub Actions Kani verification shards to run within the memory limits of hosted runners, preventing consistent OOM/preemption failures and making the CI conclusion job attainable again.

Changes:

  • Reduce Kani parallelism across all shards to --jobs 2 to avoid CBMC solver memory spikes on 16 GB runners.
  • Update timeouts: increase kani-core to 120 minutes; decrease kani-arrow to 60 minutes; keep other shards at 120 minutes.
  • Refresh the workflow’s Kani shard documentation/comments with current proof counts and rationale.

Five proofs were consuming 500-800s each (total ~2500s = 42 min on
a single thread), causing Kani CI shards to timeout or get OOM-killed.

Fixes:
- verify_hex_decode_rejects_wrong_length (805s → ~5s):
  Replace Vec heap allocation with stack array slice

- verify_parse_int_fast_no_panic_8bytes (538s → ~10s):
  Remove to_string() roundtrip (allocator modeling is expensive);
  oracle proof already covers correctness

- verify_parse_int_fast_vs_oracle (534s → ~30s):
  Reduce input from 20 bytes to 10 (still covers all i32 + most i64)

- verify_encode_bytes_field_content_compositional (502s → ~20s):
  Reduce data array from 8 to 4 bytes; reduce unwind 12 → 6

- verify_json_escape_bytes_vs_oracle (120s → ~15s):
  Reduce input from 16 to 8 bytes; reduce unwind 100 → 50

- verify_merge_child_send_result_tracks_pending_signals (556s → ~5s):
  Bound Duration millisecond values to ≤ 30_000 (full u64 solver space
  provides no extra branch coverage for a simple comparison)

Total estimated savings: ~2400s → ~85s (28x faster on the critical path).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels May 1, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review May 1, 2026 03:39

Dismissing prior approval to re-evaluate c57b2f6

@pr-rocket pr-rocket Bot changed the title Reduce Kani --jobs to 2 to prevent OOM runner kills Reduce Kani jobs and proof bounds to prevent OOM kills May 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c57b2f62fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/ffwd-core/src/otlp.rs Outdated
Comment thread crates/ffwd-core/src/scan_config.rs
- Fix rustfmt formatting in sink.rs (if/else on single line)
- Increase unwind(6) → unwind(12) on encode_bytes_field_content_compositional
  to cover encode_varint_stub's 10-iteration loop
- Add verify_parse_int_fast_overflow_boundary proof targeting i64 overflow
  (19-20 digit inputs with constrained digit-only symbols to keep solver
  tractable while covering the overflow region the 10-byte oracle proof misses)
- Update doc comments to cross-reference the overflow proof

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 1, 2026
@pr-rocket pr-rocket Bot changed the title Reduce Kani jobs and proof bounds to prevent OOM kills Lower Kani jobs and proof bounds to prevent OOM May 1, 2026
…cracker research

Document hard-won lessons on avoiding slow proofs:
- Heap allocation avoidance (Vec/String → stack arrays)
- Duration/u64 arithmetic bounding
- Input constraining for targeted proofs
- Input partitioning strategy
- Function contracts pattern (Firecracker's key technique)
- CI resource constraints (OOM thresholds)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes May 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5764b942a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/ffwd-core/src/scan_config.rs
coderabbitai[bot]
coderabbitai Bot previously requested changes May 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dev-docs/references/kani-verification.md`:
- Around line 210-215: The example uses an undefined variable `len` in the loop
over `for i in 0..len`; fix it by defining a bounded `len` or using a literal
bound so you never index past `bytes`. For example, declare `let len: usize = /*
choose or nondet value */` and constrain it with `kani::assume(len <=
bytes.len());` before the loop, or replace `for i in 0..len` with a literal like
`for i in 0..bytes.len()` to iterate safely over the `bytes` array.
- Line 179: The Vec example uses the repeat Vec syntax with kani::any(), which
fails because kani::any is not Clone; replace the vec![kani::any(); 16] usage by
constructing an iterator over the range 0..16, mapping each element to
kani::any::<u8>() (or kani::any() with an explicit Vec<u8> annotation to help
inference) and then collecting the results into a Vec<u8>, referencing the
existing symbols Vec<u8>, kani::any, map, collect and the 0..16 range.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c99c22af-ba1f-424f-8ffb-709901703d60

📥 Commits

Reviewing files that changed from the base of the PR and between c8040bc and 5764b94.

📒 Files selected for processing (1)
  • dev-docs/references/kani-verification.md

Comment thread dev-docs/references/kani-verification.md Outdated
Comment thread dev-docs/references/kani-verification.md
…t PR CI

Proofs taking >30s solver time are gated behind `#[cfg(feature = "kani-slow")]`:
- structural.rs: 6 proofs (compute_real_quotes, prefix_xor, find_char_mask,
  structural_scalar — all with 65-unwind over symbolic u64/[u8;64])
- cri.rs: 3 proofs (process_cri 48-byte, write_json_line parametric,
  json_escape oracle — all with 50+ unwind)
- otlp.rs: 3 proofs (parse_severity exhaustive, skip_field oracle + no-panic
  — 32-byte arrays)
- ffwd-kani/bytes.rs: 3 proofs (oracle contracts with 65-unwind)
- json_scanner.rs: 1 proof (next_quote 66-unwind)
- structural_iter.rs: 1 proof (advance pipeline 66-unwind)
- scan_config.rs: 1 proof (overflow boundary 20-byte)
- framer.rs: 1 proof (ranges_valid 32-byte + kissat)

CI behavior:
- PR CI: runs ~130 fast proofs only (estimated ~5 min wall-clock)
- Push-to-main / ci:full label: runs all ~149 proofs with --features kani-slow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@macroscopeapp
macroscopeapp Bot dismissed their stale review May 1, 2026 04:14

Dismissing prior approval to re-evaluate 0c77ab2

@pr-rocket pr-rocket Bot changed the title Lower Kani jobs and proof bounds to prevent OOM Prevent Kani CI OOM with bounded proofs and lower parallelism May 1, 2026
@pr-rocket pr-rocket Bot added documentation Improvements or additions to documentation enhancement New feature or request labels May 1, 2026
- Add verify_parse_int_fast_mid_range proof for 11-17 byte inputs,
  bridging the coverage gap between the main oracle (0-10) and
  overflow boundary (18-20) proofs
- Fix undefined 'len' variable in digit-constraint doc example
- Update input partitioning guidance to show three-range pattern

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
github-actions Bot dismissed coderabbitai[bot]’s stale review May 1, 2026 04:19

Auto-dismissed because every review thread opened from this change request is now resolved. If additional changes are still required, please leave a new review.

@pr-rocket pr-rocket Bot changed the title Prevent Kani CI OOM with bounded proofs and lower parallelism Add kani-slow feature gate and lower CI parallelism to 2 May 1, 2026
@pr-rocket pr-rocket Bot added the test label May 1, 2026
@gitar-bot

gitar-bot Bot commented May 1, 2026 •

Copy link
Copy Markdown

Note

Your trial team has used its Gitar budget, so automatic reviews are paused. Upgrade now to unlock full capacity. Comment "Gitar review" to trigger a review manually.
Learn more about usage limits

Code Review ✅ Approved

Reduces CI memory pressure by lowering parallelism and gating expensive proofs behind a kani-slow feature. Documentation updated with verification best practices, and mid-range proof logic added for improved coverage.

Auto-approved: The PR addresses documented OOM issues in CI by adjusting resource allocation (--jobs) and timeouts in a straightforward manner consistent with the provided diagnostic comments.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Important

Your trial ends in 2 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 381-401: PRs currently skip compiling code under cfg(feature =
"kani-slow") because --features kani-slow is only enabled on push-to-main or
when the ci:full label is present; update the CI to auto-enable the kani-slow
feature for PRs that touch any slow-proof files by detecting changed paths and
setting the feature flag for the relevant job(s). Concretely, add a step early
in the workflow to run git diff --name-only origin/main...HEAD (or use
github.event.pull_request.changed_files/path filters) to match the slow-proof
file patterns and, if matched, set an environment variable (e.g.,
ENABLE_KANI_SLOW=true) or append --features kani-slow to the cargo/kani
invocation for the build/test/proof steps referenced in the workflow so those
jobs compile and typecheck cfg(feature = "kani-slow") harnesses without
requiring the ci:full label.

In `@crates/ffwd-core/src/cri.rs`:
- Around line 1134-1139: Both slow JSON proofs need explicit solver pinning: add
the attribute #[kani::solver(kissat)] above the #[kani::proof] for both
verify_write_json_line_parametric() and verify_json_escape_bytes_vs_oracle(),
and include a short comment on the same line or just above explaining the solver
choice (e.g., "Pin solver to kissat because this ~30s proof exceeds the 10s
threshold and performs better with kissat"). Ensure you place the attribute in
the same cfg-gated blocks where the functions are defined so the proof
annotations remain contiguous.

In `@crates/ffwd-core/src/structural.rs`:
- Around line 714-717: The change removed the fast/oracle Kani proofs for
prefix_xor/compute_real_quotes; restore a reduced default (non-`kani-slow`)
oracle harness for `verify_prefix_xor` (and a small harness for
`compute_real_quotes`) that compares `prefix_xor` against the scalar reference
(`verify_prefix_xor_vs_oracle`) and uses kani::cover!() to assert both "some
bits set" and "zero bits" paths, while keeping the exhaustive 64-bit/65-unwind
variants gated by `#[cfg(feature = "kani-slow")]`; update the harnesses
referenced (`verify_prefix_xor`, `verify_prefix_xor_vs_oracle`,
`compute_real_quotes`, `verify_process_block_compositional`) so only the
expensive exhaustive tests remain behind `kani-slow` and the reduced oracle
proofs run in regular PR CI.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8fa884d7-084b-42e6-9b27-a7f1deea50c4

📥 Commits

Reviewing files that changed from the base of the PR and between 5764b94 and c92fc41.

📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • crates/ffwd-core/Cargo.toml
  • crates/ffwd-core/src/cri.rs
  • crates/ffwd-core/src/framer.rs
  • crates/ffwd-core/src/json_scanner.rs
  • crates/ffwd-core/src/otlp.rs
  • crates/ffwd-core/src/scan_config.rs
  • crates/ffwd-core/src/structural.rs
  • crates/ffwd-core/src/structural_iter.rs
  • crates/ffwd-kani/Cargo.toml
  • crates/ffwd-kani/src/bytes.rs
  • dev-docs/references/kani-verification.md

Comment thread .github/workflows/ci.yml
Comment on lines +381 to +401
# Fast vs slow proofs:
# Proofs gated behind `kani-slow` feature (>30s solver time) run only
# on push-to-main and ci:full PRs. PR CI runs fast proofs only (~5 min
# wall-clock for core shard vs ~45+ min with slow proofs).
#
# Observed proof counts and timing constraints:
# kani-core: ~130 fast + ~15 slow proofs (ffwd-core + ffwd-kani)
# Slow: structural(unwind 65), cri(unwind 52), severity
# kani-arrow: 24 proofs (ffwd-arrow) — all fast
# kani-runtime-types: 63 proofs (ffwd-runtime + ffwd-types) — all fast
# kani-io-output: 59 proofs (ffwd-io + ffwd-output +
# ffwd-diagnostics + ffwd binary) — all fast
#
# All shards use --jobs 2 (not 3 or 4). CBMC solver processes consume
# 3-5 GB each; at --jobs 3+ on 16 GB runners, memory pressure causes
# OOM kills or runner preemption (manifests as "runner shutdown signal"
# after only minutes). --jobs 2 keeps peak memory under ~10 GB.
#
# The core shard gets 120 min (slow proofs need it on main).
# Arrow gets 60 min (finishes in ~5 min, but needs compilation time).
# Runtime and IO shards get 120 min for cold-cache variance.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default PRs stop compiling the slow proof set.

With --features kani-slow only on push-to-main or ci:full, edits under the new #[cfg(feature = "kani-slow")] harnesses never typecheck on ordinary PRs. A helper rename or signature drift in those proofs now lands as a post-merge failure on main. Please auto-enable the feature when a PR touches one of the slow-proof files, even without the label.

Suggested workflow shape
 jobs:
   changes:
     name: Detect changed paths
     runs-on: ubuntu-latest
     outputs:
       kani_required: ${{ steps.filter.outputs.kani_required }}
+      kani_slow_required: ${{ steps.filter.outputs.kani_slow_required }}
       tla: ${{ steps.filter.outputs.tla }}
       frontend: ${{ steps.filter.outputs.frontend }}
       miri: ${{ steps.filter.outputs.miri }}
       rust: ${{ steps.filter.outputs.rust }}
     steps:
       - uses: actions/checkout@v6
       - uses: dorny/paths-filter@f3ceefdc7ef57bc2d8560787d4b6c33e44044cec
         id: filter
         with:
           filters: |
             kani_required:
               - 'crates/ffwd-kani/**'
               - 'crates/ffwd-core/**'
               - 'crates/ffwd-arrow/**'
               - 'crates/ffwd-types/**'
               - 'crates/ffwd-io/**'
               - 'crates/ffwd-output/**'
               - 'crates/ffwd-runtime/**'
               - 'crates/ffwd-diagnostics/**'
               - 'crates/ffwd/**'
               - 'Cargo.toml'
               - 'Cargo.lock'
               - 'dev-docs/verification/kani-boundary-contract.toml'
               - 'scripts/verify_kani_boundary_contract.py'
               - '.github/workflows/ci.yml'
+            kani_slow_required:
+              - 'crates/ffwd-core/src/structural.rs'
+              - 'crates/ffwd-core/src/structural_iter.rs'
+              - 'crates/ffwd-core/src/json_scanner.rs'
+              - 'crates/ffwd-core/src/framer.rs'
+              - 'crates/ffwd-kani/src/bytes.rs'

   kani-core:
     ...
     with:
       args: >-
         --solver kissat
         --jobs 2
         --output-format terse
         -Z function-contracts
         -Z mem-predicates
         -Z stubbing
         -p ffwd-kani
         -p ffwd-core
-        ${{ (github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'ci:full')) && '--features kani-slow' || '' }}
+        ${{ (github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'ci:full') || needs.changes.outputs.kani_slow_required == 'true') && '--features kani-slow' || '' }}

Also applies to: 420-432

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 381 - 401, PRs currently skip
compiling code under cfg(feature = "kani-slow") because --features kani-slow is
only enabled on push-to-main or when the ci:full label is present; update the CI
to auto-enable the kani-slow feature for PRs that touch any slow-proof files by
detecting changed paths and setting the feature flag for the relevant job(s).
Concretely, add a step early in the workflow to run git diff --name-only
origin/main...HEAD (or use github.event.pull_request.changed_files/path filters)
to match the slow-proof file patterns and, if matched, set an environment
variable (e.g., ENABLE_KANI_SLOW=true) or append --features kani-slow to the
cargo/kani invocation for the build/test/proof steps referenced in the workflow
so those jobs compile and typecheck cfg(feature = "kani-slow") harnesses without
requiring the ci:full label.

Comment on lines +1134 to 1139
///
/// Gated behind `kani-slow`: unwind 52 through JSON escaping takes >30s.
#[cfg(feature = "kani-slow")]
#[kani::proof]
#[kani::unwind(52)]
fn verify_write_json_line_parametric() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

wc -l crates/ffwd-core/src/cri.rs

Repository: strawgate/fastforward

Length of output: 98


🏁 Script executed:

sed -n '1130,1145p' crates/ffwd-core/src/cri.rs

Repository: strawgate/fastforward

Length of output: 733


🏁 Script executed:

sed -n '1232,1255p' crates/ffwd-core/src/cri.rs

Repository: strawgate/fastforward

Length of output: 1156


Add #[kani::solver(kissat)] to both slow JSON proofs.

Both verify_write_json_line_parametric() (line 1134) and verify_json_escape_bytes_vs_oracle() (line 1236) are documented as ~30s proofs, exceeding the 10s threshold that requires explicit solver pinning per the coding guidelines. Add #[kani::solver(kissat)] with a comment explaining the solver choice.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ffwd-core/src/cri.rs` around lines 1134 - 1139, Both slow JSON proofs
need explicit solver pinning: add the attribute #[kani::solver(kissat)] above
the #[kani::proof] for both verify_write_json_line_parametric() and
verify_json_escape_bytes_vs_oracle(), and include a short comment on the same
line or just above explaining the solver choice (e.g., "Pin solver to kissat
because this ~30s proof exceeds the 10s threshold and performs better with
kissat"). Ensure you place the attribute in the same cfg-gated blocks where the
functions are defined so the proof annotations remain contiguous.

Comment on lines +714 to +717
///
/// Gated behind `kani-slow`: 65-unwind loop over symbolic u64 takes >30s.
/// PR CI runs the fast `verify_prefix_xor_vs_oracle` instead.
#[cfg(feature = "kani-slow")]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Keep one fast oracle proof for compute_real_quotes/prefix_xor.

The comment above verify_prefix_xor now says PR CI still runs verify_prefix_xor_vs_oracle, but Lines 833-845 gate that harness too. After this change, ordinary PR Kani keeps only the submask contract for compute_real_quotes and no direct proof for prefix_xor; verify_process_block_compositional also stubs compute_real_quotes, so regressions in escape/string-mask handling will only surface on main/ci:full. Please leave a reduced default proof for these leaf primitives and reserve only the exhaustive 64-bit variants for kani-slow.

As per coding guidelines, "Bitmask operations (structural.rs, structural_iter.rs, chunk_classify.rs) must have oracle proofs against scalar reference with kani::cover!() confirming both 'some bits set' and 'zero bits' paths."

Also applies to: 750-805, 831-845

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/ffwd-core/src/structural.rs` around lines 714 - 717, The change
removed the fast/oracle Kani proofs for prefix_xor/compute_real_quotes; restore
a reduced default (non-`kani-slow`) oracle harness for `verify_prefix_xor` (and
a small harness for `compute_real_quotes`) that compares `prefix_xor` against
the scalar reference (`verify_prefix_xor_vs_oracle`) and uses kani::cover!() to
assert both "some bits set" and "zero bits" paths, while keeping the exhaustive
64-bit/65-unwind variants gated by `#[cfg(feature = "kani-slow")]`; update the
harnesses referenced (`verify_prefix_xor`, `verify_prefix_xor_vs_oracle`,
`compute_real_quotes`, `verify_process_block_compositional`) so only the
expensive exhaustive tests remain behind `kani-slow` and the reduced oracle
proofs run in regular PR CI.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working chore documentation Improvements or additions to documentation enhancement New feature or request performance Performance optimization size:L This PR changes 100-499 lines, ignoring generated files. test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants