Skip to content

Migrate to Polonius and evolve internal APIs around borrowing (#465) - #472

Open
leynos wants to merge 20 commits into
mainfrom
issue-465-migrate-to-polonius-and-evolve-internal-apis-around-borrowing
Open

Migrate to Polonius and evolve internal APIs around borrowing (#465)#472
leynos wants to merge 20 commits into
mainfrom
issue-465-migrate-to-polonius-and-evolve-internal-apis-around-borrowing

Conversation

@leynos

@leynos leynos commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

This branch migrates Netsuke to the Polonius alpha borrow-checking analysis (-Zpolonius=next) and uses the migration to evolve internal APIs towards a borrow-centric ownership model (Mode E: model evolution).

Closes #465.

The dated nightly nightly-2026-06-25 is pinned in rust-toolchain.toml, and the flag flows through every build path: .cargo/config.toml for plain Cargo, rust-analyzer, and cargo kani; the POLONIUS_FLAGS variable in the Makefile for recipes that set RUSTFLAGS; and the pinned toolchain in ci.yml, netsukefile-test.yml, and coverage-main.yml. The stable/MSRV CI matrices are removed and rust-version is dropped from Cargo.toml, since Cargo cannot express a nightly requirement; ADR-006 records the policy decision and its release consequences.

The nll-to-polonius two-pass audit was run with the compiler as the oracle; every change was verified with and without the flag:

  • Polonius-dependentNodePathRegistry::ensure_node_mut in src/graph_view/mod.rs replaces the three entry(path.clone()).or_insert(...) sites with a &mut NodeKind-returning accessor: one lookup on hits, a path clone only on insertion. It passes with -Zpolonius=next and is rejected by NLL with E0499 (tagged POLONIUS(case-3)).
  • Pass-both evolutions (habit, no toolchain caveat) — group_by consumes its key instead of cloning (src/stdlib/collections.rs); cycle detection snapshots borrowed keys (src/ir/cycle.rs); the which resolver borrows its search directories and copies them into the owned error only at the miss boundary (src/stdlib/which/env.rs).
  • Refusals — the action hash stays owned as persistent IR identity (POLONIUS-REFUSED(id-is-data) in src/ir/from_manifest_support.rs), cache hits stay cloned out of the LRU mutex (lock-boundary), and the miss-dominant string-key registration keeps its entry form.

Clone counts fell from 158 to 151 in src/ (graph_view 17→14); the clone-modify-writeback scan was empty before and after.

Review walkthrough

  • Start with docs/polonius.md for the complete audit record: rewritten sites, pass-both evolutions, refusals, non-candidates, clone counts, and the stabilization checklist.
  • Then review src/graph_view/mod.rs for the Polonius-dependent registry and src/graph_view/tests.rs for the new hit/miss accessor test.
  • Review ADR-006 with the toolchain wiring (rust-toolchain.toml, .cargo/config.toml, Makefile, workflows).
  • Note tests/kani_cfg_ui_tests.rs: trybuild discards workspace rustflags and rebuilt the crate under NLL, so the policy fixture is now compiled and run directly with the workspace rustc; its assertions are unchanged and the trybuild dev-dependency is removed.
  • Finish with the anti-regression guidance in AGENTS.md and the developers' guide.

Validation

  • make check-fmt, make lint (rustdoc, Clippy, Whitaker), make test, make markdownlint, and make nixie all pass under the pinned nightly with -Zpolonius=next.
  • cargo check without the flag fails only at the tagged POLONIUS(case-3) site with E0499, confirming the design genuinely depends on Polonius; each pass-both evolution was verified to compile under plain NLL.
  • coderabbit review --agent ran after each milestone (toolchain adoption; API evolution and documentation) with zero findings on both passes.

Notes

  • Whitaker lints under its own pinned Dylint toolchain by design and accepts the Polonius flag; Kani reads the workspace .cargo/config.toml, so cargo kani borrow-checks with the same analysis.
  • The changelog records pending changes under an "Unreleased" heading; these entries roll into the next release entry when it is cut.

References

Summary by Sourcery

Adopt a Polonius-based, borrow-centric ownership model and pin the project to a nightly Rust toolchain, updating graph view APIs, tooling, and documentation accordingly.

Enhancements:

  • Introduce a NodePathRegistry for graph view node registration so callers work with borrow-returning accessors instead of cloning paths defensively.
  • Refine borrowing patterns in cycle detection and stdlib utilities (group_by and which resolver) to snapshot and pass path data by reference where possible while documenting deliberate owned-value refusals.

Build:

  • Pin the Rust toolchain to nightly-2026-06-25 in rust-toolchain.toml and enable -Zpolonius=next globally via .cargo/config.toml and Makefile POLONIUS_FLAGS.
  • Remove the rust-version field from Cargo.toml so rust-toolchain.toml becomes the single source of truth for the compiler contract.

CI:

  • Simplify CI and netsukefile workflows to run exclusively on the pinned nightly toolchain with Polonius enabled and adjust caches and coverage upload conditions accordingly.
  • Update the coverage workflow to build and measure coverage on the same pinned nightly toolchain as the rest of CI.

Documentation:

  • Add ADR-006 and a detailed polonius.md migration log describing the Polonius adoption, audit method, and stabilization plan.
  • Extend AGENTS.md, the developers guide, netsuke-design, README, and contents to document the Polonius-based toolchain requirement and borrow-centric design guidelines.
  • Introduce a CHANGELOG with an Unreleased section capturing the Polonius migration and related changes.

Tests:

  • Replace the trybuild-based Kani cfg policy test with a direct compile-and-run harness that uses the workspace rustc and remove the trybuild dev-dependency.
  • Add targeted tests for the new NodePathRegistry accessor semantics and update which resolver tests to use borrowed directory paths.

Chores:

  • Add a project-level Cargo.lock and wire in a new .cargo/config.toml to centralize build-time Rust flags.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 55 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 58544ab8-1b89-441c-aa0c-d2e3b26fcb79

📥 Commits

Reviewing files that changed from the base of the PR and between 69efa1f and 7618f5c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (31)
  • .cargo/config.toml
  • .github/workflows/build-and-package.yml
  • .github/workflows/ci.yml
  • .github/workflows/coverage-main.yml
  • .github/workflows/netsukefile-test.yml
  • AGENTS.md
  • CHANGELOG.md
  • Cargo.toml
  • Makefile
  • README.md
  • docs/adr-006-adopt-polonius-nightly-toolchain.md
  • docs/contents.md
  • docs/developers-guide.md
  • docs/netsuke-design.md
  • docs/polonius.md
  • docs/quickstart.md
  • docs/users-guide.md
  • rust-toolchain.toml
  • src/graph_view/mod.rs
  • src/graph_view/tests.rs
  • src/ir/cycle.rs
  • src/ir/from_manifest_support.rs
  • src/stdlib/collections.rs
  • src/stdlib/which/cache.rs
  • src/stdlib/which/env.rs
  • src/stdlib/which/lookup/mod.rs
  • src/stdlib/which/lookup/tests.rs
  • src/stdlib/which/resolve_error.rs
  • tests/documentation_examples_tests.rs
  • tests/kani_cfg_ui_tests.rs
  • tests/ui/cfg_kani_policy_pass.rs

Walkthrough

Adopt pinned nightly Rust with -Zpolonius=next, align Cargo, Makefile, CI, coverage, and packaging workflows, evolve selected APIs towards borrowing, replace the Kani compile test, and document the resulting toolchain contract.

Changes

Polonius migration

Layer / File(s) Summary
Toolchain and build contract
.cargo/config.toml, rust-toolchain.toml, Makefile, Cargo.toml, .github/workflows/*
Pin nightly-2026-06-25, propagate Polonius flags, remove the Rust version and trybuild declarations, and update build workflows.
CI and test tooling alignment
.github/workflows/ci.yml, .github/workflows/netsukefile-test.yml, tests/kani_cfg_ui_tests.rs, tests/ui/*
Use one pinned toolchain, remove matrix gating, update cache keys, and compile and run the Kani fixture directly with rustc.
Borrowing-oriented API evolution
src/graph_view/*, src/ir/*, src/stdlib/collections.rs, src/stdlib/which/*
Add structured graph registration, introduce borrowed path APIs, avoid selected clones, and retain owned values at documented boundaries.
Migration documentation and contributor guidance
AGENTS.md, README.md, CHANGELOG.md, docs/*, tests/documentation_examples_tests.rs
Document the nightly policy, Polonius audit, borrowing rules, installation commands, release changes, and verification guidance.

Sequence Diagram(s)

sequenceDiagram
  participant Build
  participant Cargo
  participant RustNightly
  participant Polonius
  Build->>Cargo: invoke build, test, lint, or check
  Cargo->>RustNightly: use nightly-2026-06-25
  RustNightly->>Polonius: enable -Zpolonius=next
  Polonius-->>Build: compile with Polonius analysis
Loading

Possibly related PRs

Suggested labels: Issue

Suggested reviewers: codescene-access

Poem

Nightly stars align,
Polonius checks the paths,
Borrowed nodes now flow,
CI follows one bright pin,
Clones rest where boundaries glow.

🚥 Pre-merge checks | ✅ 20
✅ Passed checks (20 passed)
Check name Status Explanation
Title check ✅ Passed Align the title with the Polonius migration and issue #465.
Description check ✅ Passed Keep the description on-topic with the Polonius and borrow-centric API changes.
Linked Issues check ✅ Passed Satisfy the Polonius, audit, documentation, and toolchain requirements from #465.
Out of Scope Changes check ✅ Passed Keep the changeset scoped to Polonius adoption, borrowing refactors, tests, and docs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Testing (Overall) ✅ Passed Targeted unit, property, Kani, and doc-contract tests cover the changed graph, cycle, which, Kani, and install-doc behaviours; they are not vacuous.
User-Facing Documentation ✅ Passed docs/users-guide.md now explains the nightly/Polonius source-install requirement and explicit registry-install command, covering the changed user-facing behaviour.
Developer Documentation ✅ Passed Pass: docs/developers-guide.md, docs/netsuke-design.md and ADR-006 document the Polonius/toolchain changes; no execplan or locale-sync gaps found.
Module-Level Documentation ✅ Passed Repo-wide scan found 286 Rust files and none lacked a leading module docstring.
Testing (Unit And Behavioural) ✅ Passed PASS: Added tests hit real boundaries—run_netsuke_in spawns the binary, docs examples exercise CLI/JSON workflows, and unit tests cover registry and PATH edge-case invariants.
Testing (Property / Proof) ✅ Passed GraphView’s insertion-order invariant is covered by proptest, Kani is used for bounded verification, and AGENTS.md now mandates proptest/Kani/Verus for such invariants.
Testing (Compile-Time / Ui) ✅ Passed Direct rustc compile-time fixtures replace trybuild, covering cfg(kani) pass/fail cases and a compile-and-run policy check.
Unit Architecture ✅ Passed PASS: keep mutation inside explicit command paths, and expose fallibility at the boundary via Result/Option in lookup, env capture, and registry accessors.
Domain Architecture ✅ Passed Touched domain/IR code stays pure, while env/filesystem concerns remain confined to src/stdlib/which adapters and are translated into domain-shaped errors.
Observability ✅ Passed Toolchain/docs/internal borrow-refactors only; no production runtime path gained a new operational failure mode, and existing tracing/error categories remain intact.
Security And Privacy ✅ Passed No secrets, credential handling, permission widening, or sensitive-data exposure appears in the diff; changes are docs/workflow config only and keep only secret names.
Performance And Resource Use ✅ Passed PASS: New loops stay bounded (e.g. workspace max depth 6), and the changed paths mostly replace clones with borrows; no new unbounded walks or buffers appear.
Concurrency And State ✅ Passed No new shared mutable state was introduced; the only lock-backed cache change is documented, narrowly scoped, and existing tests cover cache and ordering semantics.
Architectural Complexity And Maintainability ✅ Passed PASS: NodePathRegistry and EdgeRegistrar stay local, replace repeated clone-and-insert logic, are explicitly documented/tested, and add no hidden layering or dependency cycles.
Rust Compiler Lint Integrity ✅ Passed PASS: No new dead_code/unused suppressions or fake anchors were added; the new rustc harness is narrow, and clone use reads as deliberate ownership, not lint appeasement.
✨ 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 issue-465-migrate-to-polonius-and-evolve-internal-apis-around-borrowing

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

@sourcery-ai

sourcery-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Migrates the project to a pinned Polonius-enabled nightly toolchain and refactors selected internal APIs to be borrow-centric, introducing a graph node registry abstraction, tightening which/env and cycle detector lifetimes, simplifying the Kani cfg policy test harness, and wiring CI, Makefile, and documentation around the new borrow-checking contract.

File-Level Changes

Change Details Files
Introduce NodePathRegistry and make graph-view node registration borrow-centric with a Polonius-dependent accessor, plus coverage tests.
  • Replace raw BTreeMap-based node path tracking with a NodePathRegistry wrapper that owns the BTreeMap and exposes borrow-returning accessors.
  • Implement ensure_node_mut and insert_target to avoid double lookups and only clone paths on insertion, relying on Polonius for the conditional-borrow pattern.
  • Change register_outputs and register_inputs_and_edges to use NodePathRegistry, and add tests validating hit/miss behaviour and metadata preservation.
src/graph_view/mod.rs
src/graph_view/tests.rs
Tighten borrowing in collection utilities, cycle detection, and which resolver to avoid unnecessary key/path cloning while documenting deliberate owned cases.
  • Make group_by_filter consume key_value in map entry insertion while documenting a miss-dominant refusal in GroupedValues::new.
  • Adjust CycleDetector::detect_targets to snapshot borrowed Utf8Path keys and sort/use them without cloning.
  • Change EnvSnapshot::resolved_dirs to return Vec<&Utf8Path> and thread that through resolve_error::not_found, HandleMissContext, and tests.
  • Annotate WhichResolver::try_cache and GroupedValues::new with POLONIUS-REFUSED tags explaining why owned returns or entry-based registration remain correct design choices.
  • Update resolve_error::not_found and tests to accept borrowed paths and clone only when building the error.
src/stdlib/collections.rs
src/ir/cycle.rs
src/stdlib/which/env.rs
src/stdlib/which/resolve_error.rs
src/stdlib/which/cache.rs
src/stdlib/which/lookup/mod.rs
src/stdlib/which/lookup/tests.rs
Adopt a pinned nightly toolchain with Polonius enabled globally and update CI, Makefile, and documentation to match the new toolchain and borrow-checker policy.
  • Pin rust-toolchain.toml to nightly-2026-06-25 and add a .cargo/config.toml that sets -Zpolonius=next via [build] rustflags.
  • Remove rust-version from Cargo.toml and document the nightly requirement in README and CHANGELOG.
  • Update Makefile to propagate POLONIUS_FLAGS into RUSTFLAGS for test, typecheck, and Whitaker lint recipes so Polonius is used even when RUSTFLAGS is overridden.
  • Collapse CI matrices (ci.yml, netsukefile-test.yml, coverage-main.yml) to a single nightly toolchain, adjust caching keys, and ensure coverage and linting run under the pinned nightly.
  • Add ADR-006 and polonius.md documenting the decision, migration audit, dependent/refused sites, and anti-regression guidelines, and reference them from AGENTS.md, developers-guide.md, docs contents, and netsuke-design.md.
rust-toolchain.toml
.cargo/config.toml
Cargo.toml
README.md
CHANGELOG.md
Makefile
.github/workflows/ci.yml
.github/workflows/netsukefile-test.yml
.github/workflows/coverage-main.yml
docs/adr-006-adopt-polonius-nightly-toolchain.md
docs/polonius.md
AGENTS.md
docs/developers-guide.md
docs/contents.md
docs/netsuke-design.md
Simplify the Kani cfg policy test harness to compile and run the fixture directly with workspace rustc, removing trybuild and ensuring Polonius flags are honoured.
  • Replace the trybuild-based kani cfg policy test with a helper that compiles the fixture using rustc() into a tempdir and then executes it, returning io::Result for better diagnostics.
  • Factor out compile_ui_fixture to share compilation logic between the kani policy test and rustc_with_kani_check_cfg.
  • Adjust the policy fixture comments to describe the compile-and-run contract instead of trybuild, and drop the trybuild dev-dependency from Cargo.toml.
tests/kani_cfg_ui_tests.rs
tests/ui/cfg_kani_policy_pass.rs
Cargo.toml
Record Polonius migration and toolchain choices across project documentation and guidance for contributors.
  • Introduce docs/polonius.md with the nll-to-polonius audit method, list of Polonius-dependent sites, pass-both evolutions, refusals, clone counts, and stabilization plan.
  • Add ADR-006 describing the adoption of a Polonius-enabled nightly toolchain, rationale, and consequences.
  • Extend AGENTS.md and developers-guide.md with explicit guidance on using Polonius, avoiding NLL-era workarounds, respecting POLONIUS and POLONIUS-REFUSED tags, and classifying new borrow-centric APIs.
  • Update docs/netsuke-design.md to include Polonius and borrow-centric API design in the technology choices, and register new docs in docs/contents.md.
docs/polonius.md
docs/adr-006-adopt-polonius-nightly-toolchain.md
AGENTS.md
docs/developers-guide.md
docs/netsuke-design.md
docs/contents.md

Assessment against linked issues

Issue Objective Addressed Explanation
#465 Adopt the Polonius alpha borrow checker on a pinned nightly toolchain, wiring -Zpolonius=next through Cargo, CI, rust-analyzer, and Makefile workflows, and reconcile/remodel the previous stable/MSRV policy (including rust-version metadata) via an ADR.
#465 Run the nll-to-polonius audit and evolve internal APIs toward a borrow-centric model, including implementing a borrow-returning node-path registry in graph_view with clone-on-miss semantics, classifying Polonius-dependent vs pass-both vs refused sites, tagging them in code, and recording the audit (including clone counts) in docs/polonius.md.
#465 Update project documentation and contributor guidance to reflect the Polonius-based design and toolchain contract, including README, developers-guide, netsuke-design, AGENTS, docs/contents, a new ADR, and ensuring the existing test suite and build commands run under the new contract without weakening tests.

Possibly linked issues


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

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review July 29, 2026 09:52

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai coderabbitai Bot added the Issue label Jul 29, 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: 3b3e7732fa

ℹ️ 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 .cargo/config.toml
# `-Zpolonius=next` themselves. See
# docs/adr-006-adopt-polonius-nightly-toolchain.md.
[build]
rustflags = ["-Zpolonius=next"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve Polonius settings for registry installs

Once this source is published, the documented bare cargo install netsuke runs outside the checkout and therefore receives neither this flag nor the pinned nightly: the manifest's package allow-list excludes both .cargo/config.toml and rust-toolchain.toml (Cargo's package --list help describes that command as printing the files included in the package). The packaged source now contains a Polonius-only accessor, so ordinary registry installs compile it under the user's toolchain without -Zpolonius=next and fail with E0499. Keep distributed source NLL-compatible or document and validate an install command that explicitly selects the nightly and passes the flag.

AGENTS.md reference: AGENTS.md:L205-L207

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@coderabbitai Has this now been resolved in the latest commit?

Use codegraph analysis to determine your answer.

If this comment is now resolved, please mark it as such using the API. Otherwise, please provide an AI agent prompt for the remaining work to be done to address this comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Current commit and package configuration =='
git rev-parse HEAD
printf '\n-- Cargo package fields --\n'
rg -n -A12 -B3 '^\[package\]|\b(include|exclude)\s*=' Cargo.toml || true
printf '\n-- Files Cargo says are packaged --\n'
cargo package --list --allow-dirty 2>&1 | sed -n '1,220p' || true

printf '\n== Module map ==\n'
ast-grep outline src/graph_view/mod.rs --items all --match 'NodePathRegistry|ensure_node_mut|EdgeRegistrar|from_build_graph' --view expanded

printf '\n== Borrow-centric registry symbols and callers ==\n'
rg -n -C5 '\b(NodePathRegistry|ensure_node_mut)\b' src/graph_view/mod.rs src/graph_view/tests.rs

printf '\n== Polonius-tagged sites and installation guidance ==\n'
rg -n -C4 'POLONIUS|cargo install|install netsuke|Zpolonius|nightly-2026-06-25' \
  Cargo.toml README.md docs AGENTS.md Makefile .cargo/config.toml rust-toolchain.toml \
  -g '!docs/contents.md' || true

printf '\n== Tracked package/build configuration status ==\n'
git ls-files .cargo/config.toml rust-toolchain.toml Cargo.toml README.md docs/adr-006-adopt-polonius-nightly-toolchain.md docs/polonius.md

Length of output: 1254


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== PR head =='
git rev-parse HEAD

printf '%s\n' '== Package boundary =='
sed -n '1,140p' Cargo.toml
printf '%s\n' '-- configuration files tracked by Git --'
git ls-files --stage .cargo/config.toml rust-toolchain.toml

printf '%s\n' '== Registry accessor definition and direct call graph =='
ast-grep outline src/graph_view/mod.rs --items all --match 'NodePathRegistry|ensure_node_mut|EdgeRegistrar|from_build_graph' --view expanded
rg -n -C5 '\b(NodePathRegistry|ensure_node_mut)\b' src/graph_view/mod.rs src/graph_view/tests.rs

printf '%s\n' '== Packaged-install and Polonius guidance =='
rg -n -i -C4 'cargo\s*(\+[^[:space:]]+\s*)?install|install\s+netsuke|registry|Zpolonius|nightly-2026-06-25|POLONIUS' \
  README.md Cargo.toml docs AGENTS.md .cargo/config.toml rust-toolchain.toml || true

Length of output: 74717


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Documentation contract-test map =='
ast-grep outline tests/documentation_examples_tests.rs --items all --view expanded

printf '%s\n' '== Registry-install example assertions and fixture discovery =='
rg -n -i -C6 'readme-crates-io-install|guide-crates-io-install|RUSTFLAGS=-Zpolonius=next|cargo \+nightly-2026-06-25 install netsuke|rustup toolchain install nightly-2026-06-25' \
  tests README.md docs/users-guide.md

printf '%s\n' '== All documentation-example test call sites =='
rg -n -C4 'tested-example|documentation_examples|README\.md|users-guide\.md' tests \
  -g '*.rs' -g '*.md' || true

Length of output: 753


@leynos, do not resolve this thread. The latest commit fixes the README and users’ guide, but docs/quickstart.md still tells users to install via bare cargo install netsuke (Line 11). That registry build receives neither the pinned nightly nor -Zpolonius=next, while the NodePathRegistry::ensure_node_mut code path remains explicitly Polonius-only.

The documentation-contract-test inspection also failed because repository setup was unavailable, so its coverage remains unverified.

Use this AI-agent prompt to finish the remaining work:

Fix the remaining unsupported crates.io installation instruction for Netsuke.

Context:
- `Cargo.toml` packages neither `.cargo/config.toml` nor `rust-toolchain.toml`.
- `src/graph_view/mod.rs::NodePathRegistry::ensure_node_mut` requires `-Zpolonius=next`; it is intentionally rejected by NLL.
- The supported registry installation command is:
  rustup toolchain install nightly-2026-06-25
  RUSTFLAGS=-Zpolonius=next cargo +nightly-2026-06-25 install netsuke
- `README.md` and `docs/users-guide.md` already use this command.
- `docs/quickstart.md` still says `cargo install netsuke`, which is unsupported and must not remain as a standalone installation instruction.

Required changes:
1. Update `docs/quickstart.md` to direct users to the supported pinned-nightly and Polonius registry-install command, or link unambiguously to the canonical installation instructions in `docs/users-guide.md`.
2. Inspect `tests/documentation_examples_tests.rs` and its helpers/fixtures. Add or update a contract test so every tagged registry-install example requires both:
   - `cargo +nightly-2026-06-25`
   - `RUSTFLAGS=-Zpolonius=next`
3. Search all user-facing documentation for `cargo install netsuke`. Replace any bare registry-install command or explicitly scope it to a checkout-local `cargo install --path .` invocation where the repository configuration applies.
4. Run the project’s documentation validation and relevant test target under the pinned nightly with Polonius enabled.
5. Report the changed files, the exact validation commands, and their results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/coverage-main.yml:
- Line 27: Disable persisted checkout credentials by adding persist-credentials:
false under the checkout steps in .github/workflows/coverage-main.yml lines
27-27 and .github/workflows/netsukefile-test.yml lines 22-23.

In `@docs/polonius.md`:
- Around line 23-29: Update the validation statement in the documented build
procedure to distinguish per-change no-flag compilation from the full
behavioural suite: use the no-flag build only to classify whether an individual
change depends on Polonius, and require the complete behavioural suite to run
under -Zpolonius=next. Keep the existing POLONIUS(...) classification and
toolchain outcome guidance consistent with this contract.
🪄 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 Plus

Run ID: 3e0943fc-fe41-40d0-8fbd-8d0c42fe9a20

📥 Commits

Reviewing files that changed from the base of the PR and between 23591d0 and 3b3e773.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (28)
  • .cargo/config.toml
  • .github/workflows/build-and-package.yml
  • .github/workflows/ci.yml
  • .github/workflows/coverage-main.yml
  • .github/workflows/netsukefile-test.yml
  • AGENTS.md
  • CHANGELOG.md
  • Cargo.toml
  • Makefile
  • README.md
  • docs/adr-006-adopt-polonius-nightly-toolchain.md
  • docs/contents.md
  • docs/developers-guide.md
  • docs/netsuke-design.md
  • docs/polonius.md
  • rust-toolchain.toml
  • src/graph_view/mod.rs
  • src/graph_view/tests.rs
  • src/ir/cycle.rs
  • src/ir/from_manifest_support.rs
  • src/stdlib/collections.rs
  • src/stdlib/which/cache.rs
  • src/stdlib/which/env.rs
  • src/stdlib/which/lookup/mod.rs
  • src/stdlib/which/lookup/tests.rs
  • src/stdlib/which/resolve_error.rs
  • tests/kani_cfg_ui_tests.rs
  • tests/ui/cfg_kani_policy_pass.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/rstest-bdd (auto-detected)
  • leynos/ortho-config (auto-detected)
  • leynos/shared-actions (auto-detected)
💤 Files with no reviewable changes (1)
  • Cargo.toml

Comment thread .github/workflows/coverage-main.yml
Comment thread docs/polonius.md Outdated
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
User-Facing Documentation ⚠️ Warning README now requires a pinned nightly/Polonius for source installs, but docs/users-guide.md still says Rust 1.89+ and was not changed. Update docs/users-guide.md’s install section to describe the nightly-2026-06-25/Polonius source-build requirement and keep it aligned with README.

@leynos

leynos commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@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. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

tests/documentation_examples_tests.rs

Comment on lines +157 to +163

    // Registry installs run outside a checkout, so the packaged source sees
    // neither rust-toolchain.toml nor .cargo/config.toml; the documented
    // command must select the pinned nightly and the Polonius flag itself.
    let expected_release = concat!(
        "rustup toolchain install nightly-2026-06-25\n",
        "RUSTFLAGS=-Zpolonius=next cargo +nightly-2026-06-25 install netsuke\n"
    );

❌ New issue: Large Method
installation_examples_match_source_and_release_contracts has 71 lines, threshold = 70

@leynos

leynos commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@coderabbitai

This comment was marked as resolved.

@leynos

leynos commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

The "User-Facing Documentation" pre-merge warning is stale: commit 69efa1f updated docs/users-guide.md — the "Rust 1.89 or later" prerequisite is gone, the guide now describes the pinned nightly-2026-06-25/Polonius source-build requirement, and its crates.io install block matches the README exactly. The contract test installation_examples_match_source_and_release_contracts pins both documents to the same command, so they cannot drift apart.

@coderabbitai

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- current PR head ---'
git rev-parse HEAD
git status --short

printf '%s\n' '--- user-guide source-install/toolchain references ---'
rg -n -i -C 5 'Rust 1\.89|Rust [0-9]+\.[0-9]+|nightly-2026-06-25|Polonius|cargo \+nightly|RUSTFLAGS|crates\.io|source' docs/users-guide.md

printf '%s\n' '--- README source-install/toolchain references ---'
rg -n -i -C 5 'Rust 1\.89|Rust [0-9]+\.[0-9]+|nightly-2026-06-25|Polonius|cargo \+nightly|RUSTFLAGS|crates\.io|source' README.md

printf '%s\n' '--- focused documentation contract test ---'
ast-grep outline tests/documentation_examples_tests.rs --items all --view expanded
rg -n -A125 -B10 'fn installation_examples_match_source_and_release_contracts\s*\(' \
  tests/documentation_examples_tests.rs

printf '%s\n' '--- commit claimed by the user, if present locally ---'
git show --no-patch --format='%H%n%s' 69efa1f 2>&1 || true

Length of output: 1025


@leynos: Verification is inconclusive: repository setup failed before the documentation and contract test could be inspected. Keep the warning unresolved until repository access succeeds; then validate that docs/users-guide.md contains no Rust 1.89/stable-source-build claim and that installation_examples_match_source_and_release_contracts asserts both documents’ identical nightly/Polonius install command.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
src/graph_view/mod.rs (1)

201-227: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared per-output EdgeView insertion into one helper.

register_input_edges and register_dependencies both loop for out in all_outputs(self.edge) and push an EdgeView { from: ..., to: out.clone(), class }. Factor the inner insertion into a single method (e.g. fn insert_edges(&mut self, from: &Utf8PathBuf, class_for: impl Fn(&Utf8PathBuf) -> EdgeClass)) taking the class either as a fixed value or a small closure, and call it from both sites.

♻️ Sketch of the consolidation
 impl EdgeRegistrar<'_> {
+    fn insert_edges_from(&mut self, from: &Utf8PathBuf, class_for: impl Fn(&Utf8PathBuf) -> EdgeClass) {
+        for out in all_outputs(self.edge) {
+            self.edges.insert(EdgeView {
+                from: from.clone(),
+                to: out.clone(),
+                class: class_for(out),
+            });
+        }
+    }
+
     fn register_input_edges(&mut self, input: &Utf8PathBuf, implicit: &BTreeSet<&Utf8PathBuf>) {
-        for out in all_outputs(self.edge) {
-            let class = if implicit.contains(out) {
-                EdgeClass::ImplicitOutput
-            } else {
-                EdgeClass::Explicit
-            };
-            self.edges.insert(EdgeView {
-                from: input.clone(),
-                to: out.clone(),
-                class,
-            });
-        }
+        self.insert_edges_from(input, |out| {
+            if implicit.contains(out) {
+                EdgeClass::ImplicitOutput
+            } else {
+                EdgeClass::Explicit
+            }
+        });
     }

     fn register_dependencies(&mut self, deps: &[Utf8PathBuf], class: EdgeClass) {
         for dep in deps {
             self.registry.ensure_node_mut(dep);
-            for out in all_outputs(self.edge) {
-                self.edges.insert(EdgeView {
-                    from: dep.clone(),
-                    to: out.clone(),
-                    class,
-                });
-            }
+            self.insert_edges_from(dep, |_| class);
         }
     }
 }

Also applies to: 236-295

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

In `@src/graph_view/mod.rs` around lines 201 - 227, Extract the duplicated
per-output EdgeView insertion from register_input_edges and
register_dependencies into a shared insert_edges method on the relevant view
type, accepting the source path and either a fixed EdgeClass or class-producing
closure. Have both callers delegate to this helper while preserving their
existing class selection and all_outputs(self.edge) iteration behavior.
src/stdlib/which/env.rs (1)

59-74: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid adding cwd twice in CwdMode::Always. resolved_dirs() already prepends self.cwd, so a literal . in PATH adds the same directory again. That can return duplicate matches with all=true and rescan the same directory unnecessarily; skip CurrentDir when mode is Always.

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

In `@src/stdlib/which/env.rs` around lines 59 - 74, Update resolved_dirs so
PathEntry::CurrentDir is ignored when mode is CwdMode::Always, since self.cwd is
already prepended in that mode; retain the existing CurrentDir handling for
CwdMode::Auto and omission for other modes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/developers-guide.md`:
- Around line 83-87: Update the documentation paragraph around the rustup and
.cargo/config.toml explanation to state that the configuration supplies the flag
by default, rather than applying it to every Cargo invocation. Preserve the
existing clarification that inherited RUSTFLAGS overrides .cargo/config.toml and
that Makefile recipes use POLONIUS_FLAGS.

---

Outside diff comments:
In `@src/graph_view/mod.rs`:
- Around line 201-227: Extract the duplicated per-output EdgeView insertion from
register_input_edges and register_dependencies into a shared insert_edges method
on the relevant view type, accepting the source path and either a fixed
EdgeClass or class-producing closure. Have both callers delegate to this helper
while preserving their existing class selection and all_outputs(self.edge)
iteration behavior.

In `@src/stdlib/which/env.rs`:
- Around line 59-74: Update resolved_dirs so PathEntry::CurrentDir is ignored
when mode is CwdMode::Always, since self.cwd is already prepended in that mode;
retain the existing CurrentDir handling for CwdMode::Auto and omission for other
modes.
🪄 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 Plus

Run ID: 451ed985-e12c-40b6-b8f0-22c68261325f

📥 Commits

Reviewing files that changed from the base of the PR and between 23591d0 and 69efa1f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (30)
  • .cargo/config.toml
  • .github/workflows/build-and-package.yml
  • .github/workflows/ci.yml
  • .github/workflows/coverage-main.yml
  • .github/workflows/netsukefile-test.yml
  • AGENTS.md
  • CHANGELOG.md
  • Cargo.toml
  • Makefile
  • README.md
  • docs/adr-006-adopt-polonius-nightly-toolchain.md
  • docs/contents.md
  • docs/developers-guide.md
  • docs/netsuke-design.md
  • docs/polonius.md
  • docs/users-guide.md
  • rust-toolchain.toml
  • src/graph_view/mod.rs
  • src/graph_view/tests.rs
  • src/ir/cycle.rs
  • src/ir/from_manifest_support.rs
  • src/stdlib/collections.rs
  • src/stdlib/which/cache.rs
  • src/stdlib/which/env.rs
  • src/stdlib/which/lookup/mod.rs
  • src/stdlib/which/lookup/tests.rs
  • src/stdlib/which/resolve_error.rs
  • tests/documentation_examples_tests.rs
  • tests/kani_cfg_ui_tests.rs
  • tests/ui/cfg_kani_policy_pass.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/rstest-bdd (auto-detected)
  • leynos/ortho-config (auto-detected)
  • leynos/shared-actions (auto-detected)
💤 Files with no reviewable changes (1)
  • Cargo.toml

Comment thread docs/developers-guide.md
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@lodyai
lodyai Bot force-pushed the issue-465-migrate-to-polonius-and-evolve-internal-apis-around-borrowing branch from 019181f to 27a53ff Compare July 30, 2026 09:24
codescene-access[bot]

This comment was marked as outdated.

leynos and others added 19 commits July 30, 2026 11:25
Pin `nightly-2026-06-25` in `rust-toolchain.toml` and enable the
Polonius alpha borrow-checking analysis (`-Zpolonius=next`) for every
build path:

- `.cargo/config.toml` applies the flag to plain Cargo invocations,
  rust-analyzer, and `cargo kani`.
- Makefile recipes that set `RUSTFLAGS` (which overrides the config
  table) re-state the flag via the new `POLONIUS_FLAGS` variable.
- CI collapses the stable/MSRV matrices in `ci.yml` and
  `netsukefile-test.yml` to the pinned nightly and aligns
  `coverage-main.yml`.
- `Cargo.toml` drops `rust-version = "1.89.0"`, which cannot express a
  nightly requirement.

ADR-006 records the policy decision and its release consequences. The
developers' guide, design document, README, documentation index, and a
new `CHANGELOG.md` document the toolchain contract. This prepares the
borrow-centric API evolution tracked by issue #465.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Introduce `NodePathRegistry` in `src/graph_view/mod.rs` and route the
three `entry(path.clone()).or_insert(NodeKind::Source)` sites through
`ensure_node_mut`, a get-or-insert accessor that returns
`&mut NodeKind`, performs one lookup on the hit path, and clones the
path only on insertion. Target registration moves behind
`insert_target` so callers pass borrowed paths throughout.

The accessor is the canonical Polonius problem-case-3 shape: the
`get_mut` loan escapes only via the early return, so the insertion on
the miss path is accepted under `-Zpolonius=next` and rejected by NLL
with E0499. Both outcomes were compiler-verified on
nightly-2026-06-25, and the site carries a `POLONIUS(case-3)` tag with
anti-regression guidance.

Behaviour is unchanged: the graph_view unit, snapshot, and property
suites pass as-is, and a new parameterized test pins the hit and miss
semantics of the accessor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`group_by_filter` cloned each resolved key value before passing it to
`IndexMap::entry`, but the key is not used again afterwards, so the
entry call can consume it directly.

Classification for the Polonius audit: this compiles under plain NLL as
well as `-Zpolonius=next`, so the clone was habit rather than a
borrow-checker workaround; no toolchain caveat applies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`CycleDetector::detect_targets` collected an owned clone of every
target path purely to sort them for deterministic traversal. The
target map is borrowed for the whole `'targets` lifetime, so the
snapshot can hold `&'targets Utf8Path` references instead, removing
one allocation per node on every cycle analysis.

Classification for the Polonius audit: this compiles under plain NLL
as well as `-Zpolonius=next` because the collection exists for
sorting, not to end a borrow; the owned snapshot was habit. Behaviour
is unchanged and the cycle unit and property suites pass as-is.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`EnvSnapshot::resolved_dirs` cloned the current working directory and
every `PATH` entry into an owned `Vec<Utf8PathBuf>` for each uncached
resolution, although the search loop and miss diagnostics only read
the directories. Return `Vec<&Utf8Path>` borrowed from the snapshot
instead, thread the borrowed slice through `HandleMissContext`, and
copy the paths into the owned `ResolveError::NotFound` only at the
error boundary, where the diagnostic genuinely outlives the snapshot.

Classification for the Polonius audit: compiles under plain NLL as
well as `-Zpolonius=next` — the owned returns were habit, not a
borrow-checker workaround. The lookup tests compare against borrowed
paths now; the assertions themselves are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Record the audit's deliberate refusals in source so future passes (by
humans or agents) do not convert them into borrow-returning forms:

- `register_action` keeps returning the owned action hash because the
  hash is persistent IR identity stored on every `BuildEdge` and named
  in the generated Ninja file: `POLONIUS-REFUSED(id-is-data)`.
- The which resolver's cache clones hits out of the LRU because a
  reference cannot outlive the `MutexGuard`:
  `POLONIUS-REFUSED(lock-boundary)`.
- `GroupedValues::new` keeps the owned-key `entry` form because the
  first-wins registration is miss-dominant:
  `POLONIUS-REFUSED(miss-dominant)`.

No behaviour changes; comments only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add `docs/polonius.md` recording the complete two-pass audit: the
compiler-verified `POLONIUS(case-3)` site in graph_view, the pass-both
evolutions (group_by key, cycle-detection snapshot, which resolver
directories), the tagged refusals with their permanent constraints,
the non-candidates reviewed and cleared, clone counts before and after
(158 to 151 in `src/`), and the stabilization checklist.

Add a "Borrow checker: Polonius, not NLL" section to `AGENTS.md` so
coding agents do not rewrite borrow-centric sites into double lookups,
defensive clones, or id indirection out of NLL-era habit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The `cases.pass()` trybuild case rebuilt `netsuke` as a dependency of
its scratch project, and trybuild discards ambient `RUSTFLAGS` and
workspace `build.rustflags` in favour of its own `--config` flags, so
the dependency compiled under plain NLL and rejected the
`POLONIUS(case-3)` accessor in graph_view (E0499).

The fixture only asserts on `include_str!` copies of `Cargo.toml` and
the `Makefile` and has no dependencies, so compile it with the
workspace `rustc` through the same harness the sibling check-cfg tests
use, run the produced binary, and assert both steps succeed. The
policy assertions are unchanged; drop the now-unused `trybuild`
dev-dependency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Document that trybuild replaces workspace rustflags and so cannot
build the Polonius-only crate as a fixture dependency, and that Kani
and Whitaker inherit the flag through the workspace configuration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI failed at `make lint`: `actions-rust-lang/setup-rust-toolchain`
(nested inside the shared setup-rust action) exports
`RUSTFLAGS="-D warnings"` into the job environment when the variable
is unset, and an ambient `RUSTFLAGS` overrides the
`.cargo/config.toml` `build.rustflags` table. `make lint-clippy` did
not re-state the flags, so Clippy compiled under plain NLL and
rejected the tagged `POLONIUS(case-3)` accessor with E0499.

Fix both layers:

- Pre-set `RUSTFLAGS` (including `-Zpolonius=next`) at job level in
  `ci.yml`, `netsukefile-test.yml`, and `coverage-main.yml`. The setup
  action defers to an existing value, and `cargo-llvm-cov` appends its
  instrumentation flags to it, so coverage inherits the flag too.
- Harden the Makefile: `lint-clippy` re-states the flags for Clippy,
  and the `cargo doc` and binary-build recipes append
  `$(POLONIUS_FLAGS)` to any ambient `RUSTFLAGS` so a hostile
  environment can never strip the analysis.

Verified locally by running `make lint-clippy` and `make build` with
`RUSTFLAGS="-D warnings"` exported, reproducing the CI environment;
both now pass. The harness-consequences section of `docs/polonius.md`
records the CI behaviour and flags the shared mutation workflow as
the remaining environment outside this repository's control.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeScene's delta gate flagged `register_inputs_and_edges` as a bumpy
road: three sibling loops each nesting conditional logic. Replace the
free function with an `EdgeRegistrar` that groups the edge with the
mutable projection state, splits input registration from
dependency-class registration, and shares the duplicated output chain
through a single `all_outputs` iterator (also reused by
`register_outputs`).

Behaviour is unchanged: the graph_view unit, snapshot, and property
suites pass as-is, the CodeScene delta reports no issues, and the
`POLONIUS(case-3)` accessor still verifies both ways (E0499 under
plain NLL).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The release dry run failed: `rust-build-release` invokes the shared
setup-rust composite, whose nested `setup-rust-toolchain` exports
`RUSTFLAGS="-D warnings"` into the job environment when the variable
is unset, shadowing `.cargo/config.toml` and stripping
`-Zpolonius=next` from the release cargo build (E0499 at the tagged
`POLONIUS(case-3)` site).

Pre-set `RUSTFLAGS: -Zpolonius=next` at job level in
`build-and-package.yml`, mirroring the fix already applied to the CI,
coverage, and Netsukefile workflows: the setup action defers to an
existing value, so every nested cargo invocation inherits the flag. A
companion shared-actions change exposing a `rustflags` passthrough
input is being submitted separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Disable persisted checkout credentials in `coverage-main.yml` and
  `netsukefile-test.yml`, matching the hardened checkout in `ci.yml`;
  neither job pushes, so the cached token serves no purpose.
- Clarify the validation contract in `docs/polonius.md`: the no-flag
  compile exists only to classify whether an individual change depends
  on Polonius, while the complete behavioural suite runs under
  `-Zpolonius=next`, the tree's only supported configuration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The crates.io package excludes `rust-toolchain.toml` and
`.cargo/config.toml` (and registry builds run outside a checkout, so
Cargo would not apply them regardless), meaning a bare
`cargo install netsuke` of a Polonius-dependent release would compile
under the user's default toolchain and fail with E0499. Keeping the
distributed source NLL-compatible would forfeit the borrow-centric
design this branch exists to adopt, so document and pin the explicit
install command instead:

    rustup toolchain install nightly-2026-06-25
    RUSTFLAGS=-Zpolonius=next cargo +nightly-2026-06-25 install netsuke

Update the tested-example blocks in the README and users' guide, the
contract expectation in `documentation_examples_tests.rs`, the ADR-006
release consequence, the polonius harness notes, and the changelog.
The users' guide also loses a stale "Rust 1.89 or later" prerequisite.
Source installs from a checkout are unaffected: the pinned toolchain
and workspace configuration apply there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Reword the developers' guide so `.cargo/config.toml` is described as
  supplying `-Zpolonius=next` by default rather than applying it to
  every Cargo invocation, keeping the existing note that an inherited
  `RUSTFLAGS` overrides the table and Makefile recipes re-state it via
  `POLONIUS_FLAGS`.
- Extract the duplicated per-output `EdgeView` insertion in
  `EdgeRegistrar` into a shared `insert_edges` helper taking the source
  path and a class-producing closure; both callers keep their class
  selection and `all_outputs` iteration.
- Stop `resolved_dirs` from listing the working directory twice under
  `CwdMode::Always`: the mode already prepends the working directory,
  so a current-directory `PATH` entry (an empty component) only
  duplicated it in search order and miss diagnostics. `CwdMode::Auto`
  behaviour is unchanged, and a regression test pins both modes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`installation_examples_match_source_and_release_contracts` reached 71
lines after gaining the registry-install expectations, tripping
CodeScene's large-method threshold. Move the Windows help, PATH, and
staging assertions into an `assert_windows_setup_examples` helper; the
assertions themselves are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the crates.io install-command and release-detail assertions into
a file-local `assert_release_installation_contract` helper, called
first from `installation_examples_match_source_and_release_contracts`,
resolving the CodeScene large-method finding. Expected strings, error
messages, and assertions are unchanged; the source-install checks stay
in the test and the Windows checks remain in the existing helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The quickstart still suggested a bare `cargo install netsuke`, which
registry builds cannot satisfy: the crates.io package carries neither
`rust-toolchain.toml` nor `.cargo/config.toml`, and the tree needs
`-Zpolonius=next`. Point the prerequisite at the checkout-scoped
source build and the canonical registry-install command in the users'
guide instead.

Add a contract test requiring every tagged registry-install example to
select `cargo +nightly-2026-06-25` and pass
`RUSTFLAGS=-Zpolonius=next` (checkout-scoped `cargo install --path .`
examples are exempt), and guarding the quickstart prose against
reintroducing a bare registry install.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The weave-assisted rebase left two consecutive blank lines ahead of
the "Toolchain and borrow checker" heading in the developers' guide,
failing markdownlint MD012.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

The weave-assisted rebase again left two consecutive blank lines in
the developers' guide, this time ahead of the "Temporary executable
test helpers" section that main introduced, failing markdownlint
MD012.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lodyai
lodyai Bot force-pushed the issue-465-migrate-to-polonius-and-evolve-internal-apis-around-borrowing branch from 7c483f1 to 7618f5c Compare July 30, 2026 09:28
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access 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.

No quality gates enabled for this code.

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.

Migrate to Polonius and evolve internal APIs around borrowing

1 participant