Skip to content

Kani verification for build_adjacency with tests and tooling#186

Merged
leynos merged 21 commits intomainfrom
kani-verify-build-adjacency-w7ihby
Apr 13, 2026
Merged

Kani verification for build_adjacency with tests and tooling#186
leynos merged 21 commits intomainfrom
kani-verify-build-adjacency-w7ihby

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Apr 3, 2026

Summary

  • Expands Kani-based verification for build_adjacency with repo-local harnesses colocated near production code; adds unit tests, behavioural coverage (BDD), a test-support seam, ExecPlan documentation, and tooling wrappers; updates docs and tooling without widening production APIs.
  • Introduces an ExecPlan document and related tooling wrappers; adds a Makefile target for Kani; and includes an adjacency-report seam used by test-support.
  • Shifts focus from a pure branch-rebase narrative to concrete verification work adjacent to production code, with bounded symbolic models to keep state-space tractable.

Changes

  • Added new Kani harness module colocated with production logic:
    • common/src/decomposition_advice/community_kani.rs (new file) containing bounded-model harnesses for build_adjacency.
  • Production API surface adjustments:
    • pub(crate) fn build_adjacency in common/src/decomposition_advice/community.rs to allow harness/test-support access without widening public API.
    • Added SimilarityEdge::new constructor for tests (crate-private).
  • Test-support and tests:
    • common/src/decomposition_advice/tests/adjacency.rs (new).
    • common/src/test_support/decomposition.rs updated to expose an adjacency report seam.
    • common/src/test_support/decomposition_adjacency.rs (new) providing a test-support module for adjacency observations.
  • Behavioural and integration tests:
    • common/tests/decomposition_adjacency_behaviour.rs (new).
    • common/tests/features/decomposition_adjacency.feature (new).
  • Behavioural and integration tests:
    • New test suite to exercise adjacency symmetry, bounds, and sorting.
  • Documentation and roadmaps:
    • docs/brain-trust-lints-design.md updated with 6.4.5 decisions; docs/roadmap.md updated to mark 6.4.5 done.
  • Tooling and workflow:
    • Top-level Makefile now includes a kani target.
    • Repo-local tooling wrappers added: scripts/install-kani.sh and scripts/run-kani.sh to install and run Kani with a focused harness filter.
  • ExecPlan:
    • Added docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md detailing scope, constraints, and validation plan.

Rationale

  • Keeps Kani tooling colocated near production code to minimize surface area changes and align with existing Verus sidecar pattern. Bounded symbolic models and a narrow test-support seam reduce state-space while validating core invariants (edge preservation, in-bounds indices, symmetry, and absence of spurious edges).

Notes

📎 Task: https://www.devboxer.com/task/dd8d35c4-13b6-4b91-84df-a0f46663eb18

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

Walkthrough

Enable Kani bounded-model checking: add Kani harnesses and test seam, promote visibility for testing, add installer/runner scripts and Makefile target, register cfg(kani) lint entry, and update docs, execplan and roadmap.

Changes

Cohort / File(s) Summary
Build & Kani tooling
Makefile, scripts/install-kani.sh, scripts/run-kani.sh
Add .PHONY kani target and kani target delegating to ./scripts/run-kani.sh; add installer install-kani.sh to fetch a pinned Kani release and toolchain; add run-kani.sh to prepare env, accept optional harness filter, and invoke cargo-kani.
Cargo config
common/Cargo.toml
Add [lints.rust] section to warn on unexpected cfgs and include cfg(kani) in check-cfg.
Production visibility
common/src/decomposition_advice/mod.rs, common/src/decomposition_advice/community.rs
Promote community module to pub(crate); promote build_adjacency to pub(crate); add pub(crate) SimilarityEdge::new; gate Kani-only verify module with #[cfg(kani)].
Kani harnesses
common/src/decomposition_advice/community_kani.rs
Add Kani-only module with bounded symbolic inputs (MAX_NODES=3, MAX_EDGES=3) and six #[kani::proof] harnesses asserting adjacency length, edge preservation, indices-in-bounds, symmetry, absence of spurious edges, and neighbour sorting.
Unit tests
common/src/decomposition_advice/tests.rs, common/src/decomposition_advice/tests/adjacency.rs
Add adjacency unit tests covering empty graphs, single/multiple edges, isolated nodes, neighbour ordering, and mirror-symmetry of adjacency entries; register new mod adjacency.
Test-support seam
common/src/test_support/decomposition.rs, common/src/test_support/decomposition_adjacency.rs
Add decomposition_adjacency module and public re-exports; introduce EdgeInput, AdjacencyError, AdjacencyReport with accessors/validators, and adjacency_report() that validates inputs and constructs adjacency via build_adjacency.
BDD tests & features
common/tests/decomposition_adjacency_behaviour.rs, common/tests/features/decomposition_adjacency.feature
Add rstest-bdd fixture and step definitions plus four Gherkin scenarios exercising success, rejected inputs (left >= right), empty neighbours and sorting determinism.
Documentation & roadmap
docs/brain-trust-lints-design.md, docs/execplans/...use-kani-to-verify-build-adjacency-preserves-similarity-edges.md, docs/roadmap.md, docs/developers-guide.md
Document bounded-model Kani approach, harness constraints and workflow (make kani), testing seam and helpers; add execplan and mark roadmap item 6.4.5 complete.
Minor docs
docs/adr-002-dylint-expect-attribute-macro.md
Adjust line-wrapping/formatting only; no behavioural change.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Make as Makefile
    participant Run as "scripts/run-kani.sh"
    participant Install as "scripts/install-kani.sh"
    participant CargoKani as "cargo-kani (Kani)"
    participant RustCode as "common crate (build_adjacency + harnesses)"

    Dev->>Make: make kani
    Make->>Run: invoke ./scripts/run-kani.sh
    Run->>Install: ensure Kani installed (install-kani.sh)
    Install-->>Run: return install dir and toolchain
    Run->>CargoKani: set PATH and env, run cargo-kani kani [--harness filter]
    CargoKani->>RustCode: execute Kani harnesses in common/
    RustCode-->>CargoKani: proof results (pass/fail)
    CargoKani-->>Run: exit code
    Run-->>Make: propagate exit code
    Make-->>Dev: display result
Loading

Poem

Harness the edges, constrain the small,
Verify symmetry, prevent the sprawl,
Install the pinned toolchain, run the script,
Exercise harnesses, let proofs be crypt,
Mark the roadmap, tests and docs stand tall.

🚥 Pre-merge checks | ✅ 5 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Developer Documentation ⚠️ Warning Developer's guide omits documentation for the SimilarityEdge::new(left, right, weight) pub(crate) constructor introduced in this PR. Extend the test-support APIs section in docs/developers-guide.md to document SimilarityEdge::new, its pub(crate) visibility, and its relationship to adjacency_report.
Module-Level Documentation ❓ Inconclusive Unable to access and inspect new module files to verify module-level documentation presence. Execute file inspection in an accessible environment to verify each new Rust module begins with //! or /*! docstrings and shell scripts include header comments.
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Testing ✅ Passed All new functionality has comprehensive test coverage: six Kani bounded model checker harnesses verify core build_adjacency() invariants, unit tests cover multiple scenarios, error handling is validated in test-support module, and BDD behavioural tests provide integration-level verification.
User-Facing Documentation ✅ Passed The PR introduces Kani bounded model checking as a contributor development tool, not user-facing functionality. Changes include internal verification harnesses, test-support modules (marked pub(crate) only), and developer tooling (make kani, installation scripts). No public APIs or lint behaviour alterations affect end-users.
Description check ✅ Passed The description comprehensively outlines all major changes (Kani harnesses, test-support seam, documentation, tooling) and aligns closely with the changeset.
Title check ✅ Passed The pull request title directly and comprehensively captures the main scope: Kani verification for build_adjacency, paired with tests and tooling infrastructure.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kani-verify-build-adjacency-w7ihby

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

codescene-delta-analysis[bot]

This comment was marked as outdated.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 3, 2026

Reviewer's Guide

Implements a Kani-based bounded model checking workflow for the build_adjacency helper in common::decomposition_advice, including colocated Kani harnesses, a repo-local Kani sidecar (install/run scripts and make kani), and new unit, behavioural, and test-support code to exercise adjacency behaviour through a narrow seam without widening production APIs, alongside documentation and roadmap updates for roadmap item 6.4.5.

Sequence diagram for adjacency_report using build_adjacency

sequenceDiagram
    participant BehaviourTest as BehaviourTestDecompositionAdjacency
    participant TestSupport as TestSupportDecomposition
    participant Community as CommunityModule
    participant Report as AdjacencyReport

    BehaviourTest->>TestSupport: adjacency_report(node_count, edges)
    TestSupport->>TestSupport: validate edges (bounds, left < right)
    alt invalid_input
        TestSupport-->>BehaviourTest: Err(String)
    else valid_input
        TestSupport->>Community: build_adjacency(node_count, &edges)
        Community-->>TestSupport: adjacency Vec<Vec<(usize,u64)>>
        TestSupport->>Report: construct AdjacencyReport(adjacency)
        TestSupport-->>BehaviourTest: Ok(AdjacencyReport)
        BehaviourTest->>Report: is_symmetric(), all_indices_in_bounds(), is_sorted(), neighbours_of(...)
        Report-->>BehaviourTest: assertions data
    end
Loading

Class diagram for build_adjacency, Kani harnesses, and adjacency test-support seam

classDiagram
    class CommunityModule {
        +pub(crate) fn build_adjacency(node_count usize, edges & [SimilarityEdge]) Vec~Vec~(usize,u64)~~
    }

    class SimilarityEdge {
        -left usize
        -right usize
        -weight u64
        +pub(crate) fn new(left usize, right usize, weight u64) SimilarityEdge
        +pub(crate) fn left() usize
        +pub(crate) fn right() usize
        +pub(crate) fn weight() u64
    }

    class CommunityKaniModule {
        +const MAX_NODES usize
        +const MAX_EDGES usize
        +fn constrained_edges(node_count usize) Vec~SimilarityEdge~
        +fn verify_build_adjacency_length()
        +fn verify_build_adjacency_preserves_edges()
        +fn verify_build_adjacency_indices_in_bounds()
        +fn verify_build_adjacency_symmetry()
        +fn verify_build_adjacency_sorted_neighbours()
    }

    class TestSupportDecomposition {
        +fn adjacency_report(node_count usize, edges Vec~SimilarityEdge~) Result~AdjacencyReport,String~
    }

    class AdjacencyReport {
        +fn is_symmetric() bool
        +fn all_indices_in_bounds() bool
        +fn is_sorted() bool
        +fn neighbours_of(node usize) Vec~(usize,u64)~
    }

    class BehaviourTestDecompositionAdjacency {
        +bdd_scenarios()
    }

    CommunityModule "1" o-- "many" SimilarityEdge
    CommunityKaniModule ..> CommunityModule : uses build_adjacency
    CommunityKaniModule ..> SimilarityEdge : constructs
    TestSupportDecomposition ..> CommunityModule : calls build_adjacency
    TestSupportDecomposition ..> SimilarityEdge : uses
    TestSupportDecomposition "1" o-- "1" AdjacencyReport
    BehaviourTestDecompositionAdjacency ..> TestSupportDecomposition : uses adjacency_report
    BehaviourTestDecompositionAdjacency ..> AdjacencyReport : asserts properties
Loading

File-Level Changes

Change Details Files
Expose and instrument build_adjacency for verification and tests while keeping it crate-internal.
  • Promoted build_adjacency from private to pub(crate) and kept it in the community module to allow internal callers.
  • Added a SimilarityEdge::new constructor used by test-support and unit tests for ergonomic edge creation.
  • Exposed the community module itself as pub(crate) from decomposition_advice::mod to let test_support and Kani harnesses access adjacency internals.
  • Registered a #[cfg(kani)] child module in community.rs that routes to the new community_kani.rs verification file.
common/src/decomposition_advice/community.rs
common/src/decomposition_advice/mod.rs
Add Kani bounded-model harnesses colocated with build_adjacency and wire them into a repo-local Kani toolchain workflow.
  • Created community_kani.rs with shared constrained-edge generation and five #[kani::proof] harnesses checking adjacency length, edge preservation, index bounds, symmetry, and neighbour sorting under tight bounds (MAX_NODES=3, MAX_EDGES=3, unwind(7)).
  • Added scripts/install-kani.sh to pin and install Kani 0.67.0 into a cache dir, create a cargo-kani symlink, install the matching nightly via rustup, and symlink it as toolchain for Kani.
  • Added scripts/run-kani.sh to set up LD_LIBRARY_PATH, PATH, and CC, then run cargo-kani against the common crate with an optional harness filter defaulting to verify_build_adjacency.
  • Extended the Makefile with a kani phony target that invokes the new runner, and updated Rust lints in common/Cargo.toml with check-cfg = ['cfg(kani)'] to silence unexpected_cfgs.
  • Documented Kani workflow and modelling decisions in docs/brain-trust-lints-design.md under a new "Implementation decisions (6.4.5)" section, and marked roadmap item 6.4.5 as done.
common/src/decomposition_advice/community_kani.rs
scripts/install-kani.sh
scripts/run-kani.sh
Makefile
common/Cargo.toml
docs/brain-trust-lints-design.md
docs/roadmap.md
Introduce a narrow test-support seam and unit tests to exercise adjacency construction without widening production APIs.
  • Added common/src/test_support/decomposition_adjacency.rs defining EdgeInput, AdjacencyReport, and helpers to validate declarative edges against the production contract, call build_adjacency, and expose observation methods (node_count, neighbours_of, all_indices_in_bounds, is_symmetric, is_sorted).
  • Wired the new test-support module into test_support::decomposition via a private mod adjacency and public re-exports of AdjacencyReport, EdgeInput, and adjacency_report.
  • Added focused unit tests in common/src/decomposition_advice/tests/adjacency.rs that construct SimilarityEdge via new and assert empty graphs, both-direction insertion, sorted neighbour lists, isolated nodes, and symmetry over a small multi-edge graph.
  • Registered the new unit-test module from common/src/decomposition_advice/tests.rs by adding a mod adjacency; declaration.
common/src/test_support/decomposition_adjacency.rs
common/src/test_support/decomposition.rs
common/src/decomposition_advice/tests/adjacency.rs
common/src/decomposition_advice/tests.rs
Add rstest-bdd behavioural coverage for adjacency through the test-support seam.
  • Created common/tests/decomposition_adjacency_behaviour.rs defining an AdjacencyWorld fixture, BDD steps (given/when/then) that build up EdgeInput sets and call adjacency_report, plus helper assertions over AdjacencyReport (symmetry, in-bounds indices, empty neighbours, sorted neighbours).
  • Added common/tests/features/decomposition_adjacency.feature with four scenarios: symmetric neighbour lists for valid edges, rejection of malformed edge input (e.g., left >= right), isolated nodes having empty neighbour lists, and multiple neighbours for a node appearing sorted.
  • Ensured BDD scenarios are bound to tests via #[scenario(..., index = N)] attributes, following existing decomposition behaviour patterns, and updated a stale dev-dependency comment in common/Cargo.toml to reference rstest-bdd 0.5.x.
  • ExecPlan doc notes and validates these behavioural tests as part of the guardrails and success criteria.
common/tests/decomposition_adjacency_behaviour.rs
common/tests/features/decomposition_adjacency.feature
common/Cargo.toml
docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@leynos leynos changed the title Plan Kani verification for build_adjacency (6.4.5) Implement Kani verification for build_adjacency (6.4.5) Apr 3, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

@devboxerhub devboxerhub bot force-pushed the kani-verify-build-adjacency-w7ihby branch from 2879d10 to bf86635 Compare April 6, 2026 02:20
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos leynos marked this pull request as ready for review April 8, 2026 00:43
sourcery-ai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

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

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: 851fcccb3e

ℹ️ 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".

codescene-delta-analysis[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai bot added the Roadmap label Apr 8, 2026
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: 3

Caution

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

⚠️ Outside diff range comments (1)
docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md (1)

544-547: ⚠️ Potential issue | 🟡 Minor

Use consistent -ize spelling: "localization" not "localisation".

Per en-GB-oxendict conventions, use the -ize suffix. The document already uses "localization" elsewhere (line 572).

Triage: [type:spelling]

Proposed fix
-- **Five separate proof harnesses for failure localisation**: the five
+- **Five separate proof harnesses for failure localization**: the five
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`
around lines 544 - 547, Replace the British spelling "localisation" with the
consistent American spelling "localization" wherever it appears in this document
(the occurrence flagged uses "localisation"); update the single word to
"localization" to match the existing usage elsewhere and ensure consistency
across the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@common/tests/features/decomposition_adjacency.feature`:
- Around line 13-17: The scenario title "Malformed edge input is rejected" is
ambiguous because the step "And an edge from 2 to 1 with weight 5" is in-bounds
for a 3-node graph; clarify the invariant by either renaming the scenario to
indicate the canonical-order requirement (e.g., "Rejected when edge endpoints
are not in canonical left < right order") or change the step to use an
out-of-range endpoint (e.g., use node index 3 or higher) if you intend to test
out-of-bounds rejection; update the Scenario header and/or the step "And an edge
from 2 to 1 with weight 5" accordingly to reflect which invariant is under test.

In `@docs/brain-trust-lints-design.md`:
- Around line 544-547: Replace the British spelling "localisation" with the
American "localization" in the sentence that starts "Five separate proof
harnesses for failure localisation" so it reads "Five separate proof harnesses
for failure localization"; search for the exact phrase "Five separate proof
harnesses for failure localisation" (or occurrences of "failure localisation")
and update them to "failure localization" to maintain the -ize convention.

In `@scripts/install-kani.sh`:
- Around line 63-74: Set the RUSTUP_TOOLCHAIN environment variable so Cargo uses
the Kani-installed toolchain: after determining toolchain_tag in
scripts/install-kani.sh (and when creating the symlink at
install_dir/toolchain), ensure run-kani.sh exports RUSTUP_TOOLCHAIN using that
same toolchain_tag (or read the pinned version from
install_dir/rust-toolchain-version) immediately after the PATH setup so Cargo
will prefer the Kani toolchain; update run-kani.sh to export
RUSTUP_TOOLCHAIN="${toolchain_tag}" (or the read value) before invoking
cargo/rustup commands.

---

Outside diff comments:
In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`:
- Around line 544-547: Replace the British spelling "localisation" with the
consistent American spelling "localization" wherever it appears in this document
(the occurrence flagged uses "localisation"); update the single word to
"localization" to match the existing usage elsewhere and ensure consistency
across the file.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5da14c08-12f2-44e9-8312-bb97e3c0b186

📥 Commits

Reviewing files that changed from the base of the PR and between 502edb6 and 1838af3.

📒 Files selected for processing (16)
  • Makefile
  • common/Cargo.toml
  • common/src/decomposition_advice/community.rs
  • common/src/decomposition_advice/community_kani.rs
  • common/src/decomposition_advice/mod.rs
  • common/src/decomposition_advice/tests.rs
  • common/src/decomposition_advice/tests/adjacency.rs
  • common/src/test_support/decomposition.rs
  • common/src/test_support/decomposition_adjacency.rs
  • common/tests/decomposition_adjacency_behaviour.rs
  • common/tests/features/decomposition_adjacency.feature
  • docs/brain-trust-lints-design.md
  • docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md
  • docs/roadmap.md
  • scripts/install-kani.sh
  • scripts/run-kani.sh

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 8, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

common/src/decomposition_advice/community_kani.rs

Comment on file

fn verify_build_adjacency_sorted_neighbours() {
    let node_count = constrained_node_count();
    let edges = constrained_edges(node_count);
    let adjacency = build_adjacency(node_count, &edges);

    for bucket in &adjacency {
        for window in bucket.windows(2) {
            assert!(window[0].0 <= window[1].0);
        }
    }
}

❌ New issue: Code Duplication
The module contains 2 functions with similar structure: verify_build_adjacency_indices_in_bounds,verify_build_adjacency_sorted_neighbours

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

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 the current code and only fix it if needed.

Inline comments:
In `@docs/brain-trust-lints-design.md`:
- Around line 528-530: Update the description so it accurately states that
scripts/run-kani.sh runs all Kani harnesses by default and only applies a filter
when a specific harness argument is supplied; replace the current sentence that
claims it invokes the pinned cargo-kani binary filtering to
verify_build_adjacency by default with text noting the default "run all
harnesses" behavior and that passing a harness name causes the script to filter
to that harness, and ensure the make kani reference reflects this default
behavior.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 203fb15a-ce43-49e6-81e6-dd455e8cb821

📥 Commits

Reviewing files that changed from the base of the PR and between e164d38 and 1413f92.

📒 Files selected for processing (3)
  • common/tests/features/decomposition_adjacency.feature
  • docs/brain-trust-lints-design.md
  • scripts/run-kani.sh

codescene-delta-analysis[bot]

This comment was marked as outdated.

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 the current code and only fix it if needed.

Inline comments:
In `@docs/brain-trust-lints-design.md`:
- Around line 540-544: In the sentence under the "Harness inputs constrained to
the production edge contract" paragraph (the sentence mentioning
`build_similarity_edges` and `kani::assume`) insert a comma before the
coordinating conjunction "so" to correctly separate the independent clauses
(i.e., change "...no duplicate unordered pairs. The Kani harnesses enforce these
same `kani::assume` preconditions, so the proof covers exactly the inputs that
production code can generate.").
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b49fe0c4-0d3e-44a9-8f81-ce0e54bcb870

📥 Commits

Reviewing files that changed from the base of the PR and between 1413f92 and c20df17.

📒 Files selected for processing (1)
  • docs/brain-trust-lints-design.md

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

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: 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 `@docs/developers-guide.md`:
- Line 64: The section heading "Kani Bounded Model Checking" is title case;
rename it to sentence case to match docs style by changing the heading text used
in the markdown (the string "Kani Bounded Model Checking") to sentence case
(e.g., "Kani bounded model checking") so the heading conforms to the project's
documentation style rules.
- Around line 154-156: The phrase "behavior-driven" in the documentation
sentence describing the common::test_support::decomposition module should use
en-GB spelling; replace "behavior-driven" with "behaviour-driven" in that line
(e.g., the sentence starting "for integration and behavior-driven tests:") so
the docs conform to the en-GB-oxendict guideline.
- Around line 177-179: Update the markdown link in developers-guide.md so it
correctly points from docs/developers-guide.md to the execplan file under
docs/execplans: replace the current broken relative target with a relative path
that starts from the docs folder (e.g.,
./execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md)
so the link text
"6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md"
resolves correctly.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6271bd29-e185-4853-a6c8-9e114f7bb8dc

📥 Commits

Reviewing files that changed from the base of the PR and between c20df17 and fbbd0f3.

📒 Files selected for processing (2)
  • docs/brain-trust-lints-design.md
  • docs/developers-guide.md

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 11, 2026

@coderabbitai Have the following now been resolved?

Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity.

Please address the comments from this code review:

## Overall Comments
- In `scripts/run-kani.sh`, `LD_LIBRARY_PATH` is set for the toolchain lib, but on macOS this should be `DYLD_LIBRARY_PATH` instead; consider branching on `uname` so the dynamic library path is wired correctly on both Linux and Darwin.
- `AdjacencyReport::neighbours_of` indexes `self.neighbours[node]` directly and will panic on an out-of-range node index; since this is an external test-support API, consider returning an `Option<&[(usize, u64)]>` or at least asserting bounds with a clearer error message to make misuses and failing scenarios easier to diagnose.
- The Kani harnesses repeat slightly different `node_count` assumptions (`> 0 && <= MAX_NODES` vs `<= MAX_NODES`); factoring node-count generation and assumptions into a single helper alongside `constrained_edges` would reduce the risk of future divergence between harnesses.

## Individual Comments

### Comment 1
<location path="scripts/run-kani.sh" line_range="24" />
<code_context>
+if [ -n "${HARNESS_FILTER}" ]; then
+    "${CARGO_KANI_BIN}" kani --harness "${HARNESS_FILTER}"
+else
+    "${CARGO_KANI_BIN}" kani --harness 'verify_build_adjacency'
+fi
</code_context>
<issue_to_address>
**issue (bug_risk):** The default harness name passed to `cargo-kani` does not match any of the defined proof functions.

In `community_kani.rs`, the harnesses are named `verify_build_adjacency_length`, `_preserves_edges`, `_indices_in_bounds`, `_symmetry`, and `_sorted_neighbours`; none is `verify_build_adjacency`. As written, the default branch will always fail when run without `HARNESS_FILTER`. Either drop `--harness` to run all harnesses, or update this to use the actual harness names (e.g., multiple `--harness` flags or a shared prefix plus an explicit filter).
</issue_to_address>

### Comment 2
<location path="docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md" line_range="360" />
<code_context>
+helper or report seam rather than through higher-level decomposition
+suggestions.
+
+### Milestone 4: add behavioural coverage with `rstest-bdd`
+
+Add an integration-test pair:
</code_context>
<issue_to_address>
**issue (review_instructions):** BDD is used as an acronym in this section without being defined on first use in the document.

In the Milestone 4 section and below (for example, "Suggested BDD scenarios"), BDD is used without ever being expanded. To satisfy the acronym rule, please introduce it on first use, such as "behaviour-driven development (BDD) scenarios", and then use "BDD" thereafter.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Define uncommon acronyms on first use.

</details>
</issue_to_address>

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== scripts/run-kani.sh ==="
fd 'run-kani.sh' --exec cat {}

echo ""
echo "=== decomposition_adjacency.rs (test_support) ==="
fd 'decomposition_adjacency.rs' --search-path common/src/test_support --exec cat {}

echo ""
echo "=== community_kani.rs ==="
fd 'community_kani.rs' --exec cat {}

echo ""
echo "=== execplan BDD context (first 50 lines around 'BDD' and 'Milestone 4') ==="
fd '6-4-5-use-kani*' --exec grep -n 'BDD\|behaviour-driven\|Milestone 4' {}

Length of output: 13259


@leynos — here is the status of each item:

# Comment Status
Overall 1 scripts/run-kani.shuname branch for DYLD_LIBRARY_PATH vs LD_LIBRARY_PATH ✅ Resolved
Overall 2 AdjacencyReport::neighbours_of returns Option<&[(usize, u64)]> ✅ Resolved
Overall 3 Kani harnesses — symbolic_adjacency helper extracted ✅ Resolved
Individual 1 run-kani.sh default branch no longer passes a non-existent harness name ✅ Resolved
Individual 2 BDD acronym expanded on first use in the execplan doc ❌ Not resolved

Individual Comment 2 — still outstanding

The BDD acronym appears without expansion as early as line 67 of docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md:

Each BDD step may parse at most 3 values in addition to the …

The expansion behaviour-driven development (BDD) only arrives at line 376. Move the expansion to line 67 (its first occurrence), then use the abbreviation freely thereafter. This does not violate en-GB-oxendict conventions and imposes no cyclomatic complexity change, so the requirement stands.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 11, 2026

@coderabbitai are you satisfied that the introduced proof is substantive, rigorous, and well-founded?

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== community_kani.rs ==="
fd 'community_kani.rs' --exec cat {}

echo ""
echo "=== community.rs (production build_adjacency) ==="
fd 'community.rs' --search-path common/src/decomposition_advice --exec cat {}

Length of output: 10541


@leynos — overall, yes: the proof is substantive and well-founded. Here is a detailed assessment.


What the proof gets right

Property coverage is complete for the stated contract. The five harnesses collectively assert everything build_adjacency is specified to do:

Harness Property
verify_build_adjacency_length output has exactly node_count buckets
verify_build_adjacency_preserves_edges every input edge appears forward and reverse with the correct weight
verify_build_adjacency_indices_in_bounds no neighbour index ≥ node_count
verify_build_adjacency_symmetry for every stored (node → neighbour, w) the mirror (neighbour → node, w) exists
verify_build_adjacency_sorted_neighbours each bucket is non-decreasing by neighbour index

Constraint generation correctly mirrors the production contract. constrained_edges enforces left < right < node_count, weight > 0, and the seen[left][right] deduplication precisely reflects the guarantees build_similarity_edges provides to callers. Critically, all three assumptions hold before the seen array is accessed, so there is no symbolic out-of-bounds access hidden in the helper.

The bounded model is maximally dense. With MAX_NODES = 3, the maximum number of distinct undirected edges is C(3, 2) = 3, which equals MAX_EDGES. The harnesses therefore cover the complete edge-population for the chosen node bound.

unwind(7) is conservative and sufficient. The deepest loop nest is active_count (≤ 3 iterations) driving the edge construction, plus Rust's sort_by on buckets of at most 2 elements. 7 comfortably exceeds the reachable depth.

Weight fidelity is doubly verified — both verify_build_adjacency_preserves_edges (checks weight == edge.weight) and verify_build_adjacency_symmetry (checks mirror_weight == weight) confirm that weights are not corrupted or dropped.


Two genuine gaps worth noting

1. No exclusion property.
None of the harnesses assert that build_adjacency only emits edges that were present in the input. A buggy implementation that injected extra symmetric, in-bounds edges would pass all five proofs. An exclusion harness would look like:

#[kani::proof]
#[kani::unwind(7)]
fn verify_build_adjacency_no_spurious_edges() {
    let (node_count, edges, adjacency) = symbolic_adjacency();
    kani::assume(node_count > 0);

    for (node, bucket) in adjacency.iter().enumerate() {
        for &(neighbour, weight) in bucket {
            let in_input = edges.iter().any(|e| {
                (e.left == node && e.right == neighbour && e.weight == weight)
                    || (e.right == node && e.left == neighbour && e.weight == weight)
            });
            assert!(in_input);
        }
    }
}

2. Sort verification is limited to 2-element lists.
With MAX_NODES = 3, no node can have more than 2 neighbours, so verify_build_adjacency_sorted_neighbours only exercises 0-, 1-, and 2-element buckets. A sort defect that manifests only at 3+ elements is invisible to this harness. Raising MAX_NODES to 4 (C(4,2) = 6 edges, MAX_EDGES = 6) would allow degree-3 lists and expose such bugs, at the cost of a larger CBMC search space. Given the comment about combinatorial explosion in sort_by's control-flow graph, the current bound is a conscious engineering trade-off; it is worth recording explicitly in the harness documentation.


Minor observation

kani::assume(node_count > 0) in verify_build_adjacency_preserves_edges and verify_build_adjacency_symmetry is technically redundant: when node_count = 0, the right < node_count constraint inside constrained_edges is unsatisfiable, so edges is always empty and the assertion loops never execute. The proof outcome is unchanged. The assumption is harmless and documents intent, but it slightly overstates the necessity of the guard.


Summary: the proof is correct, honestly scoped, and covers the primary contract of build_adjacency. The two gaps are an unverified exclusion property and sort coverage limited to 2-element lists. Whether to address them depends on your confidence in the implementation and your appetite for extending the bounded model.

@devboxerhub devboxerhub bot force-pushed the kani-verify-build-adjacency-w7ihby branch from 1a8189c to fc961c2 Compare April 12, 2026 17:04
codescene-delta-analysis[bot]

This comment was marked as outdated.

…jacency length check

Replaced assert!(adjacency.len() == node_count) with assert_eq!(adjacency.len(), node_count) to improve clarity and provide better failure messages in the test function verify_build_adjacency_length.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Add Kani-based verification for build_adjacency and tests Kani verification for build_adjacency with tests and test-support Apr 12, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

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: 7

♻️ Duplicate comments (1)
common/tests/decomposition_adjacency_behaviour.rs (1)

129-132: 🧹 Nitpick | 🔵 Trivial

Rename the scenario binding function to match canonical-order rejection semantics.

Align the function name with the updated feature scenario text to prevent intent drift.

Proposed refactor
 #[scenario(path = "tests/features/decomposition_adjacency.feature", index = 1)]
-fn scenario_malformed_edge_input_is_rejected(world: AdjacencyWorld) {
+fn scenario_edges_not_in_canonical_order_are_rejected(world: AdjacencyWorld) {
     let _ = world;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@common/tests/decomposition_adjacency_behaviour.rs` around lines 129 - 132,
Rename the test scenario function to reflect the canonical-order rejection
semantics by renaming the function scenario_malformed_edge_input_is_rejected to
scenario_malformed_edge_input_rejected_canonical_order (and update any
references or imports accordingly); keep the same #[scenario(path =
"tests/features/decomposition_adjacency.feature", index = 1)] annotation and
AdjacencyWorld parameter so the scenario binding remains intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@common/src/decomposition_advice/community_kani.rs`:
- Around line 169-190: Add an inline NOTE/TODO immediately above the assertion
inside verify_build_adjacency_sorted_neighbours to call out the MAX_NODES = 3
coverage limitation (that bucket.windows(2) only exercises 0–2 element sorts and
defects at 3+ elements are invisible). Reference the assertion using
bucket.windows(2) / assert!(window[0].0 <= window[1].0) so maintainers see the
limitation at the exact check and can find the surrounding explanation in the
function-level comment.

In `@common/src/test_support/decomposition_adjacency.rs`:
- Around line 134-143: The helper has_mirror currently indexes
neighbours[neighbour] unsafely; add a precondition check to make the intent
explicit by inserting a debug_assert!(neighbour < neighbours.len(), "has_mirror:
neighbour index out of bounds - callers (e.g. adjacency_report) must guarantee
valid indices") and then rewrite the body to use
neighbours.get(neighbour).map_or(false, |list| list.iter().any(|&(mirror,
mirror_weight)| mirror == node && mirror_weight == weight)) so release builds
won't panic but debug builds will assert if invariants are violated.

In `@docs/brain-trust-lints-design.md`:
- Around line 536-538: The acronym "CBMC" must be expanded at first mention in
this subsection; change the sentence containing "CBMC" (the one starting "These
bounds are kept deliberately small because Rust's standard `sort_by` generates
deeply nested loops that cause CBMC state-space explosion...") to include the
full term before the acronym, e.g., "the C Bounded Model Checker (CBMC)" or more
standard "the C Bounded Model Checker (CBMC)", so the expanded term appears
immediately before "(CBMC)" on first use and subsequent mentions keep using
"CBMC".

In `@docs/developers-guide.md`:
- Around line 137-140: Replace the first occurrence of the acronym "CBMC" with
its expanded form "CBMC (C Bounded Model Checker)" and leave subsequent mentions
as "CBMC"; update the sentence in the "Bounded symbolic inputs" paragraph that
currently reads about CBMC so it now reads "...cause CBMC (C Bounded Model
Checker) state-space explosion..." ensuring only the first use is expanded and
the rest of the document keeps the acronym.

In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`:
- Around line 391-393: Update the unhappy-path bullet in the docs so its
rejection condition matches the canonical-order case: replace the phrase
"out-of-range endpoint" with a clear `left >= right` rejection description
(ensure the wording matches the implemented and retrospective sections elsewhere
in this document) so the test-support wrapper unhappy-path text aligns with the
shipped canonical-order rejection case.

In `@scripts/install-kani.sh`:
- Around line 48-51: Update the curl invocation that downloads the Kani asset
(the curl command using variables asset_name, KANI_RELEASE_TAG, and tmp_dir) to
add bounded retry and timeout controls: use --retry 3 (not --retry-all-errors),
--connect-timeout 20 and --max-time 300 so transient network glitches are
retried a few times and each attempt has connection and overall time limits
before writing the tarball to "${tmp_dir}/${asset_name}" and extracting to
"${install_root}".
- Line 2: The script currently uses "set -eu" which can miss failures in
pipelines and then proceeds to create a broken symlink when toolchain_dir is
empty; change to "set -euo pipefail" and after computing toolchain_dir (the
variable populated by the grep pipeline) add a validation block that checks
toolchain_dir is non-empty and is a directory (or readable) before calling ln
-s; if the check fails, print a clear error via echo or >&2 and exit 1 so the
symlink step (ln -s ...) is never attempted with an invalid path.

---

Duplicate comments:
In `@common/tests/decomposition_adjacency_behaviour.rs`:
- Around line 129-132: Rename the test scenario function to reflect the
canonical-order rejection semantics by renaming the function
scenario_malformed_edge_input_is_rejected to
scenario_malformed_edge_input_rejected_canonical_order (and update any
references or imports accordingly); keep the same #[scenario(path =
"tests/features/decomposition_adjacency.feature", index = 1)] annotation and
AdjacencyWorld parameter so the scenario binding remains intact.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 91bde17c-e870-49ef-9e16-9812a15988ea

📥 Commits

Reviewing files that changed from the base of the PR and between 1a8189c and e2fff3d.

📒 Files selected for processing (18)
  • Makefile
  • common/Cargo.toml
  • common/src/decomposition_advice/community.rs
  • common/src/decomposition_advice/community_kani.rs
  • common/src/decomposition_advice/mod.rs
  • common/src/decomposition_advice/tests.rs
  • common/src/decomposition_advice/tests/adjacency.rs
  • common/src/test_support/decomposition.rs
  • common/src/test_support/decomposition_adjacency.rs
  • common/tests/decomposition_adjacency_behaviour.rs
  • common/tests/features/decomposition_adjacency.feature
  • docs/adr-002-dylint-expect-attribute-macro.md
  • docs/brain-trust-lints-design.md
  • docs/developers-guide.md
  • docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md
  • docs/roadmap.md
  • scripts/install-kani.sh
  • scripts/run-kani.sh

…ce test safety checks

- Added retry and timeout options for kani asset download to improve robustness.
- Added verification for kani Rust toolchain directory presence to prevent setup failures.
- Added debug_assert in has_mirror to catch out-of-bounds indexing early.
- Adjusted has_mirror to use get() with fallback to prevent panics due to invalid indices.
- Updated comments and docs formatting for CBMC references.
- Clarified scenario function name to better reflect test purpose.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Kani verification for build_adjacency with tests and test-support Kani verification for build_adjacency with tests and repo-local tooling Apr 12, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

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: 7

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

Inline comments:
In `@common/src/decomposition_advice/community_kani.rs`:
- Around line 154-165: The current verify_build_adjacency_no_spurious_edges
harness only checks provenance of each adjacency entry and misses duplicate
entries; update verify_build_adjacency_no_spurious_edges (which consumes
symbolic_adjacency returning node_count, edges, adjacency) to also compute for
each node the expected_degree by counting edges where edge.left == node or
edge.right == node and assert_eq!(adjacency[node].len(), expected_degree) before
iterating buckets, so duplicated adjacency entries will fail the proof.

In `@common/src/test_support/decomposition_adjacency.rs`:
- Around line 16-20: Add Rustdoc field-level comments to the public struct
EdgeInput: add /// comments above the fields `left`, `right`, and `weight`
describing their meaning and constraints — e.g., that `left` and `right` are
node indices in canonical order (left <= right) and that `weight` is a
non-negative u64 representing the edge weight — so generated docs show the field
semantics and positivity/canonical-order contract for `EdgeInput`.
- Around line 175-207: The public API returns Result<AdjacencyReport, String>
from adjacency_report and validate_edges; replace this opaque String with a
semantic error enum (e.g., AdjacencyError) that derives std::error::Error via
thiserror and implements Display, then change signatures of adjacency_report and
validate_edges to return Result<AdjacencyReport, AdjacencyError> and
Result<Vec<SimilarityEdge>, AdjacencyError> respectively; add enum variants for
NonCanonicalEdge {index, left, right}, EndpointOutOfRange {index, right,
node_count}, ZeroWeight {index}, and propagate those variants from the checks in
validate_edges (include the index and offending values in the variants) so
callers can match on structured failure cases, and update any callers/tests to
expect the new error type.

In `@docs/brain-trust-lints-design.md`:
- Around line 577-580: Replace the phrase "One unhappy-path BDD scenario
validates test-support input rejection" with "One unhappy-path behaviour-driven
development (BDD) scenario validates test-support input rejection" so that the
acronym BDD is expanded on first use; update the occurrence in the docs section
that contains "adjacency_report" and "build_adjacency" to keep the surrounding
sentence unchanged except for the expanded term.

In `@docs/developers-guide.md`:
- Around line 205-206: Update the documentation text that describes the
EdgeInput struct so the acronym BDD is expanded on first use: change the phrase
"for BDD scenarios" to "for behaviour-driven development (BDD) scenarios" when
describing **`EdgeInput`** to introduce the acronym before reuse.

In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`:
- Around line 142-145: Update the progress bullet that currently reads "all 5
shipped harnesses" to "all 6 shipped harnesses" so the log reflects the added
proof (verify_build_adjacency_no_spurious_edges); edit the text around the `make
kani` completion line to replace "5" with "6" and ensure wording remains
consistent with the rest of the document.

In `@scripts/install-kani.sh`:
- Around line 45-60: After extracting the downloaded Kani tarball into
install_root, immediately verify the expected binary kani_driver_bin exists and
is executable; if it does not, print a clear error to stderr and exit non‑zero
so we fail fast (this prevents creating a broken cargo_kani_bin symlink later).
Update the block that downloads and extracts the bundle (the if [ ! -x
"${kani_driver_bin}" ] branch) to perform this check right after tar -xzf and
before the subsequent symlink logic, using kani_driver_bin and cargo_kani_bin as
the referenced symbols.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2a2b4d38-1f41-4f57-925d-0b8a48dfa9eb

📥 Commits

Reviewing files that changed from the base of the PR and between e2fff3d and 5c9d494.

📒 Files selected for processing (7)
  • common/src/decomposition_advice/community_kani.rs
  • common/src/test_support/decomposition_adjacency.rs
  • common/tests/decomposition_adjacency_behaviour.rs
  • docs/brain-trust-lints-design.md
  • docs/developers-guide.md
  • docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md
  • scripts/install-kani.sh

… errors to adjacency_report

- Introduce AdjacencyError enum for typed validation errors instead of string messages
- Validate edges for non-canonical order, out-of-range endpoints, and zero weights with detailed errors
- Update adjacency_report signature to return Result with AdjacencyError
- Add unit tests covering new error cases
- Update consumers and tests to handle new error type
- Minor docs updates to reflect error handling improvements

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
codescene-delta-analysis[bot]

This comment was marked as outdated.

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: 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 `@common/src/test_support/decomposition_adjacency.rs`:
- Around line 85-108: The Rustdoc examples use the wrong crate import path
(common::...), causing doctest failures; update each executable doctest to
import the real crate name (whitaker_common) instead—e.g. change occurrences in
the examples that reference adjacency_report, EdgeInput, node_count,
neighbours_of (and any other runnable examples in this file) from
common::test_support::decomposition::... to
whitaker_common::test_support::decomposition::..., and apply the same
replacement for all executable Rustdoc blocks in this file (including the other
ranges called out).

In `@docs/developers-guide.md`:
- Around line 192-206: Update the API summary to reflect that adjacency_report
returns Result<AdjacencyReport, AdjacencyError> (not a bare AdjacencyReport):
change the first bullet to state the Result return type and describe the error
path, list and briefly describe the AdjacencyError variants that can be produced
(e.g., out-of-bounds, unsorted/canonical-order, non-positive weight,
duplicate/invalid edges) and how callers should handle the Result (e.g.,
pattern-match, unwrap, or propagate), and ensure the AdjacencyReport and its
methods (is_symmetric, all_indices_in_bounds, is_sorted, neighbours_of) and
EdgeInput are unchanged but note they live on the Ok branch of the Result.

In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`:
- Around line 325-336: Update the “minimum required assertions” list to include
the shipped no-spurious-edges check as an additional harness assertion (so the
checklist reflects six harnesses), by adding an item describing the exclusion
property implemented by verify_build_adjacency_no_spurious_edges (the function
in community_kani.rs) that ensures no spurious edges are present after building
adjacency; keep the existing five assertions intact and add this new assertion
text consistent with the others so the document and the later retrospective both
reflect the shipped proof.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b1f1853f-6286-45f7-9d11-575e29476898

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9d494 and 6e557e9.

📒 Files selected for processing (8)
  • common/src/decomposition_advice/community_kani.rs
  • common/src/test_support/decomposition.rs
  • common/src/test_support/decomposition_adjacency.rs
  • common/tests/decomposition_adjacency_behaviour.rs
  • docs/brain-trust-lints-design.md
  • docs/developers-guide.md
  • docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md
  • scripts/install-kani.sh

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 12, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

common/src/decomposition_advice/community_kani.rs

Comment on file

fn verify_build_adjacency_no_spurious_edges() {
    let (node_count, edges, adjacency) = symbolic_adjacency();
    kani::assume(node_count > 0);

    for (node, bucket) in adjacency.iter().enumerate() {
        let expected_degree = edges
            .iter()
            .filter(|edge| edge.left == node || edge.right == node)
            .count();
        assert_eq!(bucket.len(), expected_degree);

        for &(neighbour, weight) in bucket {
            let in_input = edges.iter().any(|e| {
                (e.left == node && e.right == neighbour && e.weight == weight)
                    || (e.right == node && e.left == neighbour && e.weight == weight)
            });
            assert!(in_input);
        }
    }
}

❌ New issue: Complex Method
verify_build_adjacency_no_spurious_edges has a cyclomatic complexity of 9, threshold = 9

@coderabbitai

This comment was marked as resolved.

…ncy_report error handling

- Adjusted documentation for `adjacency_report` to return a Result with `AdjacencyError` variants.
- Clarified edge input validation and error handling in developer guide and design docs.
- Updated code examples to use `whitaker_common` crate and handle errors properly.
- Enhanced execplan documentation to include spurious edge verification step.

These changes improve clarity on test-support input validation and error scenarios without altering production code behavior.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
codescene-delta-analysis[bot]

This comment was marked as outdated.

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 the current code and only fix it if needed.

Inline comments:
In
`@docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md`:
- Around line 25-27: Replace the first standalone "CBMC" mention with its
expanded form "C Bounded Model Checker (CBMC)" and leave subsequent uses as
"CBMC"; locate the initial occurrence of the token "CBMC" in the sentence
starting "make kani installs or reuses..." and update that single instance so
the acronym is defined on first use.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d86dfa44-0f91-4225-a41b-dd577a37c67a

📥 Commits

Reviewing files that changed from the base of the PR and between 6e557e9 and 206bfe5.

📒 Files selected for processing (4)
  • common/src/test_support/decomposition_adjacency.rs
  • docs/brain-trust-lints-design.md
  • docs/developers-guide.md
  • docs/execplans/6-4-5-use-kani-to-verify-build-adjacency-preserves-similarity-edges.md

…ification proof

Extracted helper functions `incident_degree` and `is_edge_in_input` from inline code in the `verify_build_adjacency_no_spurious_edges` proof to improve readability and maintainability.

These functions count incident edges and check edge existence regardless of orientation, respectively, simplifying assertions in the verification harness.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Kani verification for build_adjacency with tests and repo-local tooling Kani verification for build_adjacency with tests, BDD, and repo-local tooling Apr 12, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

…ll and run scripts

Added detailed usage documentation to `scripts/install-kani.sh` and `scripts/run-kani.sh` explaining environment variables, arguments, and script behavior. Also updated the developers guide to document the new `SimilarityEdge::new` constructor for internal use, clarifying API usage and test support patterns.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Kani verification for build_adjacency with tests, BDD, and repo-local tooling Kani verification for build_adjacency with tests and tooling Apr 12, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== docs/developers-guide.md — SimilarityEdge mentions ==="
fd 'developers-guide.md' --exec grep -n 'SimilarityEdge\|similarity_edge\|new(left' {}

echo ""
echo "=== New Rust module files — first 15 lines each ==="
for f in \
    common/src/decomposition_advice/community_kani.rs \
    common/src/decomposition_advice/tests/adjacency.rs \
    common/src/test_support/decomposition_adjacency.rs \
    common/tests/decomposition_adjacency_behaviour.rs; do
    echo "--- $f ---"
    head -15 "$f" 2>/dev/null || echo "(not found)"
done

echo ""
echo "=== Shell scripts — first 20 lines each ==="
for s in scripts/install-kani.sh scripts/run-kani.sh; do
    echo "--- $s ---"
    head -20 "$s" 2>/dev/null || echo "(not found)"
done

Length of output: 4326


@leynos — both checks are now fully resolved.

Check Status Evidence
Developer Documentation (SimilarityEdge::new) ✅ Resolved docs/developers-guide.md line 184 now documents SimilarityEdge::new(left, right, weight), its pub(crate) visibility, and its role as the bridge to adjacency_report.
Module-Level Documentation — Rust modules ✅ Resolved All four new .rs files open with //! docstrings.
Module-Level Documentation — Shell scripts ✅ Resolved Both scripts/install-kani.sh and scripts/run-kani.sh now carry full header comments (purpose, usage, arguments, environment variables) immediately after the shebang.

No further work is required for either check.

@leynos leynos merged commit 417079d into main Apr 13, 2026
5 checks passed
@leynos leynos deleted the kani-verify-build-adjacency-w7ihby branch April 13, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant