Skip to content

Prevent manifest fixture overwrites (#61) - #545

Open
lodyai[bot] wants to merge 5 commits into
mainfrom
issue-61-replace-namedtempfile-persist-with-more-explicit-file-creation-method
Open

Prevent manifest fixture overwrites (#61)#545
lodyai[bot] wants to merge 5 commits into
mainfrom
issue-61-replace-namedtempfile-persist-with-more-explicit-file-creation-method

Conversation

@lodyai

@lodyai lodyai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

This branch replaces overwrite-capable manifest persistence with an
explicit no-clobber operation. It retains atomic same-directory staging and
treats a target created concurrently as satisfying the manifest contract.

Closes #61.

Review walkthrough

Validation

  • cargo nextest run -p test_support --all-features: 74 passed.
  • cargo nextest run --test bdd_tests --all-features: 245 passed.
  • make check-fmt, make test, make typecheck, and make lint: passed.
  • coderabbit review --agent: 0 findings.

References

Summary by Sourcery

Prevent manifest fixture persistence from overwriting existing manifest files while maintaining race-tolerant behavior.

Bug Fixes:

  • Ensure manifest persistence uses a no-clobber operation so pre-existing manifest files are not overwritten.

Tests:

  • Add a regression test verifying that persisting a staged manifest leaves an existing manifest file and its contents unchanged.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 783a0648-e7d3-47f9-80a9-b4fe1fc8589d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary

  • Prevent overwriting existing manifest files during persistence.
  • Preserve atomic same-directory staging.
  • Treat concurrent regular-file creation as successful.
  • Reject concurrent directory creation with IsADirectory.
  • Report other persistence errors.
  • Add Rustdoc and public-boundary regression coverage for no-clobber behaviour.
  • Add bounded property-based coverage for controlled target-state interleavings.
  • Confirm that the specified tests, formatting, type-checking, and linting commands pass.

Walkthrough

Manifest persistence now creates files without overwriting existing manifests. It tolerates concurrent creation, rejects directory targets, and preserves other persistence errors. Tests use a shared workspace fixture and cover these behaviours.

Changes

Manifest persistence

Layer / File(s) Summary
Prevent manifest overwrites
test_support/src/manifest.rs
persist_manifest_file now uses non-clobbering persistence. It tolerates an existing regular file, returns IsADirectory for directory targets, and preserves other errors. Shared workspace fixtures and rstest support tests for existing files, directories, read-only parents, and missing parents.

Suggested labels: Issue

Suggested reviewers: leynos

Poem

Guard the manifest from overwrite.
Keep existing contents safe.
Reject directories clearly.
Let concurrent creation pass.
Test each path with care.


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (2 errors, 4 warnings, 2 inconclusive)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Tests cover overwrite prevention and directory rejection through private persist_manifest_file, but no public ensure_manifest_exists race test or bounded coverage of all required states exists. Add a deterministic public-API seam for raced file and directory creation, assert content and errors, and add bounded property-based coverage for missing, existing, and raced targets.
Unit Architecture ❌ Error The new race path uses fs::is_dir and fs::exists, which return bool and hide metadata I/O failures; tests call private persist_manifest_file, not public ensure_manifest_exists. Use fallible metadata checks at the command boundary, propagate non-NotFound errors, document the no-clobber contract, and test raced files and directories through ensure_manifest_exists.
Developer Documentation ⚠️ Warning The changed public test-support API adds no-clobber and concurrent-creation behaviour, but both commits change only test_support/src/manifest.rs; the developer guide does not document these rules. Add a test_support::ensure_manifest_exists section to docs/developers-guide.md documenting no-clobber persistence, raced files, and raced-directory errors.
Testing (Unit And Behavioural) ⚠️ Warning Tests cover missing paths and direct no-clobber helper calls, but no behavioural test drives ensure_manifest_exists through raced files or directories; bounded interleaving/property coverage is a... Add a deterministic interleaving seam and test through ensure_manifest_exists; assert raced file contents remain unchanged and raced directories return IsADirectory. Add bounded property cases.
Testing (Property / Proof) ⚠️ Warning The no-clobber invariant spans missing, file, directory, and raced states, but manifest.rs adds only fixed rstest cases and no proptest or bounded model check. Add bounded proptest coverage through ensure_manifest_exists for all required states and controlled interleavings. Assert unchanged contents and IsADirectory errors.
Concurrency And State ⚠️ Warning The private helper documents no-clobber handling, but tests bypass exported ensure_manifest_exists and contain no deterministic race or interleaving coverage. Document the guarantee on ensure_manifest_exists; add a deterministic check-to-persist seam and bounded tests for raced files, raced directories, and relevant states.
Module-Level Documentation ❓ Inconclusive Assessment pending source inspection. Inspect changed Rust modules and their module-level documentation.
Rust Compiler Lint Integrity ❓ Inconclusive Investigation is still in progress; no verdict has been submitted yet. Inspect the complete PR diff and module/lint configuration before deciding.
✅ Passed checks (12 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change replaces overwrite-capable persistence with no-clobber behaviour and adds relevant coverage, satisfying issue #61.
Out of Scope Changes check ✅ Passed The fixture, concurrency, and regression-test changes support the requested no-clobber persistence behaviour and add no unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
User-Facing Documentation ✅ Passed The change only modifies the unpublished, test-only test_support crate; no end-user interface changes require docs/users-guide.md updates.
Testing (Compile-Time / Ui) ✅ Passed Treat the check as not applicable: the PR changes runtime filesystem persistence only, with no compile-time or UI output. Focused rstest cases assert file preservation and directory errors.
Domain Architecture ✅ Passed The change is confined to test_support manifest-fixture persistence; no core domain model, command, repository, or transport code changed.
Observability ✅ Passed Pass: the change is confined to non-published test_support fixture code, not production paths, and returns contextual I/O errors at failure boundaries; no production telemetry is required.
Security And Privacy ✅ Passed The change only hardens test manifest creation with no-clobber persistence; review found no secrets, trust-boundary bypass, unsafe input sink, or broadened permissions.
Performance And Resource Use ✅ Passed The change adds only bounded filesystem checks on the rare AlreadyExists path and retains one staged write plus one no-clobber persist; it adds no unbounded loops, collections, retries, or hot-pa...
Architectural Complexity And Maintainability ✅ Passed Keep the change: it modifies one existing helper, adds no dependencies or public layers, reuses NamedTempFile and rstest, and localises the fixture to reduce test duplication.
Title check ✅ Passed The title accurately describes the no-clobber manifest change and links issue #61.
Description check ✅ Passed The description directly explains the manifest persistence change, regression coverage, validation, and linked issue.
📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #61

✨ 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-61-replace-namedtempfile-persist-with-more-explicit-file-creation-method

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

codescene-access[bot]

This comment was marked as outdated.

@sourcery-ai

sourcery-ai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR changes manifest fixture persistence to use a no-clobber atomic persist operation and adds a regression test to ensure existing manifest files are never overwritten while preserving race-tolerant behavior.

File-Level Changes

Change Details Files
Switch manifest persistence to a no-clobber operation while preserving race-tolerant semantics.
  • Replace use of overwrite-capable NamedTempFile::persist with NamedTempFile::persist_noclobber for manifest files.
  • Maintain handling of AlreadyExists errors as a successful outcome, treating concurrently created targets as satisfying the manifest contract.
  • Update manifest persistence helper documentation comment to describe the new no-overwrite behavior and concurrency tolerance.
test_support/src/manifest.rs
Add a regression test verifying existing manifests are not overwritten by persistence.
  • Import std::io::Write to support writing staged manifest contents in tests.
  • Create a pre-existing manifest file in a temporary directory, then stage a replacement manifest and call persist_manifest_file.
  • Assert that the manifest contents remain unchanged after persistence, ensuring no overwrite occurs.
test_support/src/manifest.rs

Assessment against linked issues

Issue Objective Addressed Explanation
#61 Replace use of NamedTempFile::persist for manifest files with a non-overwriting, explicit persistence method to prevent unintended file overwrites.

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.

Persist staged manifest fixtures without replacing an existing target.
Treat a concurrent creation as success and cover that no-clobber path.
@lodyai
lodyai Bot force-pushed the issue-61-replace-namedtempfile-persist-with-more-explicit-file-creation-method branch from adfd1f1 to d9f5dce Compare August 9, 2026 02:43
codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review August 9, 2026 02:53

@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 Aug 9, 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: d9f5dce7bc

ℹ️ 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 test_support/src/manifest.rs Outdated

@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 `@test_support/src/manifest.rs`:
- Around line 269-274: Extract the repeated TempDir creation and UTF-8 path
conversion from the manifest tests into a shared rstest fixture returning the
temporary directory and manifest path. Apply the fixture to all four manifest
tests, including
persisting_manifest_tolerates_existing_file_without_overwriting, and replace
each duplicated setup with the fixture values.
- Around line 107-109: Update the AlreadyExists branch in persist_manifest_file
to inspect manifest_path: return an IsADirectory error when the raced target is
a directory, and preserve success only for an existing non-directory target. Add
a regression test covering persist_manifest_file with a directory destination.
🪄 Autofix

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: bda5f391-8665-4f48-b782-531f57942afa

📥 Commits

Reviewing files that changed from the base of the PR and between 76456df and d9f5dce.

📒 Files selected for processing (1)
  • test_support/src/manifest.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/whitaker (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread test_support/src/manifest.rs Outdated
Comment thread test_support/src/manifest.rs Outdated
codescene-access[bot]

This comment was marked as outdated.

Verify targets after no-clobber persistence reports `AlreadyExists` so
existing files remain acceptable while directory targets are rejected.

Share manifest test workspace setup and cover the raced-directory path.
codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Aug 9, 2026

Copy link
Copy Markdown
Owner

@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 o11y, code safety, documentation and validation coverage as in scope).

❌ Failed checks (3 warnings, 4 inconclusive)

Check name Status Explanation Resolution
User-Facing Documentation ⚠️ Warning The public test_support::ensure_manifest_exists behaviour changed, but docs/users-guide.md does not document its no-clobber and concurrent-creation behaviour. Document the changed manifest persistence behaviour in the applicable users' guide, or show that this unpublished test-support API is out of scope.
Testing (Unit And Behavioural) ⚠️ Warning The regression test calls private persist_manifest_file directly; no public-boundary or BDD/E2E test exercises the changed no-clobber persistence behaviour. Add an integration or behavioural test through ensure_manifest_exists that exercises the race/creation contract and verifies the target remains unchanged.
Testing (Property / Proof) ⚠️ Warning The patch introduces no-clobber invariants across filesystem states and creation orderings, but manifest.rs has only example-based tests and no property test or bounded model. Add a substantive proptest or bounded model for existing and missing targets, varied contents, and both creation orderings; document the limits of race coverage.

@coderabbitai

This comment was marked as resolved.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor
✅ 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: 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 `@test_support/src/manifest.rs`:
- Around line 102-105: Update the public `ensure_manifest_exists` Rustdoc to
explicitly document that it does not overwrite an existing target and tolerates
a concurrently created non-directory target as satisfying the manifest-exists
contract. Retain the private helper’s documentation for implementation details.
- Around line 289-334: Extend the public-boundary tests for
ensure_manifest_exists rather than testing persist_manifest_file directly. Add a
test-only seam immediately before persist_manifest_file that deterministically
creates the target file or directory, then assert existing file contents remain
unchanged and directory targets return IsADirectory with the target path in the
error. Cover all five bounded race states as explicit deterministic cases,
avoiding scheduling-dependent tests.
🪄 Autofix

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: 99b8e563-24d3-4ed4-b84c-857f156fb547

📥 Commits

Reviewing files that changed from the base of the PR and between 76456df and 5cfed52.

📒 Files selected for processing (1)
  • test_support/src/manifest.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/whitaker (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread test_support/src/manifest.rs
Comment thread test_support/src/manifest.rs Outdated
Repository owner deleted a comment from coderabbitai Bot Aug 9, 2026
Describe preservation of existing and concurrently created file targets,
directory rejection, atomic staging, and the controlled proof boundary.
@wafflecat-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed.

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.

Document the no-clobber contract and exercise all controlled target
creation orderings through a test-only persistence seam.

Keep generated staged content, existing files, and directory errors under
bounded property coverage without asserting arbitrary scheduler behaviour.
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

Inspect manifest paths through a fallible test-support filesystem wrapper
so inaccessible metadata is never mistaken for an absent target.

Exercise the exported manifest helper with a scoped pre-persist hook and
document the controlled no-clobber contract for fixture authors.

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

Gates Failed
Enforce advisory code health rules (1 file with Code Duplication)

Our agent can fix these. Install it.

Gates Passed
5 Quality Gates Passed

Reason for failure
Enforce advisory code health rules Violations Code Health Impact
fs_tests.rs 1 advisory rule 10.00 → 9.39 Suppress

See analysis details in CodeScene

Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

Comment thread test_support/src/fs_tests.rs

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

@leynos

leynos commented Aug 12, 2026

Copy link
Copy Markdown
Owner

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

test_support/src/fs_tests.rs

Comment on lines +90 to +103

fn inspect_path_propagates_errors_other_than_not_found(temp_dir: TempDir) -> anyhow::Result<()> {
    let temp = temp_dir?;
    let file = temp.path().join("regular-file");
    write(&file, b"fixture")?;

    let Err(error) = inspect_path(file.join("child")) else {
        anyhow::bail!("traversing through a regular file should fail");
    };
    anyhow::ensure!(
        error.kind() != io::ErrorKind::NotFound,
        "traversal through a file should not be reported as absence, got {error:?}"
    );
    Ok(())
}

❌ New issue: Code Duplication
The module contains 2 functions with similar structure: inspect_path_propagates_errors_other_than_not_found,try_is_file_propagates_errors_other_than_not_found

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR metadata and changed files =='
gh pr view 545 --repo leynos/netsuke \
  --json number,url,headRefName,baseRefName,updatedAt,files,statusCheckRollup \
  --jq '{
    number, url, headRefName, baseRefName, updatedAt,
    files: [.files[] | {path, additions, deletions}],
    checks: [.statusCheckRollup[]? | {name, status, conclusion, detailsUrl}]
  }'

echo '== Relevant files =='
fd -t f -a '^(manifest\.rs|tests\.rs|fs\.rs|lib\.rs|developers-guide\.md|Cargo\.toml|AGENTS\.md)$' \
  test_support docs . 2>/dev/null | sort

echo '== Manifest module outline =='
ast-grep outline test_support/src/manifest.rs --items all --view expanded 2>/dev/null || true

echo '== Manifest implementation and tests =='
cat -n test_support/src/manifest.rs 2>/dev/null || true
printf '\n== Separate manifest tests, if present ==\n'
cat -n test_support/src/manifest/tests.rs 2>/dev/null || true

echo '== Filesystem wrapper API =='
ast-grep outline test_support/src/fs.rs --items all --view expanded 2>/dev/null || true
rg -n -C 5 \
  'pub\s+(?:enum|fn)\s+(?:Target|.*metadata|.*exist|.*dir)|\b(?:metadata|symlink_metadata|exists|is_dir)\s*\(' \
  test_support/src/fs.rs test_support/src/manifest.rs 2>/dev/null || true

echo '== Public API exports and documentation =='
rg -n -C 5 \
  '\bensure_manifest_exists\b|no-clobber|noclobber|concurrent|raced|IsADirectory|manifest fixture' \
  test_support/src/lib.rs test_support/src/manifest.rs docs/developers-guide.md 2>/dev/null || true

echo '== Property-test dependency and manifest test usage =='
rg -n -C 4 \
  '^(proptest|rstest)\s*=|\bproptest!\s*\{|TestCaseError|ensure_manifest_exists(?:\s*\()?' \
  Cargo.toml test_support/Cargo.toml test_support/src/manifest.rs test_support/src/manifest/tests.rs 2>/dev/null || true

echo '== Linked issue =='
gh issue view 61 --repo leynos/netsuke --json number,state,title,url \
  --jq '{number,state,title,url}'

Length of output: 70971


@leynos, treat all six reported checks as resolved on the current PR branch.

Check Status Evidence
Testing (Overall) Resolved test_support/src/manifest/tests.rs uses the exported ensure_manifest_exists with a deterministic scoped pre-persist hook. It tests raced file and raced directory targets.
Unit Architecture Resolved test_support/src/fs.rs adds fallible PathState inspection. test_support/src/manifest.rs uses fs::inspect_path at target, persistence-race, parent, and ancestor decision points. It propagates errors other than NotFound.
Developer Documentation Resolved docs/developers-guide.md now has a test_support::ensure_manifest_exists section. It documents no-clobber persistence, raced files, raced directories, fallible inspection, staging, and the controlled-ordering limit.
Testing (Unit And Behavioural) Resolved The raced-file test asserts Ok(expected_path) and byte-identical competing contents. The raced-directory test asserts io::ErrorKind::IsADirectory. Both call ensure_manifest_exists.
Testing (Property / Proof) Resolved The bounded 16-case proptest! covers missing, existing file, raced file, existing directory, and raced directory states. It generates bounded staged and competing content. It states that it tests controlled creation orderings, not arbitrary scheduler or filesystem behaviour.
Concurrency And State Resolved The test-only hook runs after initial target inspection and before persist_noclobber. Its guard restores prior state on drop. Production builds do not contain the hook.

Do not create a new GitHub issue. Open issue #61 covers the work.

GitHub CI shows a successful build-test check and successful required build checks. The supplied evidence does not show direct exit statuses for make check-fmt, make lint, and make test. Report those command results in the PR description or a follow-up comment before merge if the repository requires explicit validation evidence.


✏️ Learnings added
Learnt from: leynos
URL: https://github.com/leynos/netsuke/pull/545

Timestamp: 2026-08-12T00:33:17.011Z
Learning: For PR reviews in `leynos/netsuke`, treat warnings as required work. Treat observability, code safety, documentation, and validation coverage as in scope. If required work is out of scope and no existing issue covers it, propose a GitHub follow-up issue.

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

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Current PR and target file status =='
gh pr view 545 --repo leynos/netsuke --json number,headRefName,updatedAt,url \
  --jq '{number, headRefName, updatedAt, url}'
git status --short

echo '== Filesystem test module outline =='
ast-grep outline test_support/src/fs_tests.rs --items all --view expanded

echo '== Reported tests and nearby helpers =='
rg -n -C 18 \
  'fn\s+(inspect_path_propagates_errors_other_than_not_found|try_is_file_propagates_errors_other_than_not_found)\b|fn\s+.*propagates_errors_other_than_not_found\b' \
  test_support/src/fs_tests.rs

echo '== Test-module imports and complete local helper map =='
sed -n '1,240p' test_support/src/fs_tests.rs

echo '== Filesystem API symbols under test =='
ast-grep outline test_support/src/fs.rs --items all --view expanded
rg -n -C 6 \
  'pub\s+(?:enum|fn)\s+(?:PathState|inspect_path|try_is_file)\b|fn\s+(?:inspect_path|try_is_file)\b' \
  test_support/src/fs.rs test_support/src/fs_tests.rs

Length of output: 13210


@test_support/src/fs_tests.rsinspect_path_propagates_errors_other_than_not_found, try_is_file_propagates_errors_other_than_not_found

Fix this duplication. The current PR branch contains identical setup and assertions in both tests. Keep both test names. Extract the shared setup and non-NotFound assertion into one private test helper.

Use a generic closure so the helper accepts both return types:

fn assert_traversal_through_file_propagates_non_not_found<T>(
    temp_dir: TempDir,
    inspect: impl FnOnce(&Path) -> io::Result<T>,
) -> anyhow::Result<()> {
    let temp = temp_dir?;
    let file = temp.path().join("regular-file");
    write(&file, b"fixture")?;

    let Err(error) = inspect(&file.join("child")) else {
        anyhow::bail!("traversing through a regular file should fail");
    };
    anyhow::ensure!(
        error.kind() != io::ErrorKind::NotFound,
        "traversal through a file should not be reported as absence, got {error:?}"
    );
    Ok(())
}

Import std::path::Path. Then reduce the two tests to calls of this helper:

assert_traversal_through_file_propagates_non_not_found(temp_dir, try_is_file)
assert_traversal_through_file_propagates_non_not_found(temp_dir, inspect_path)

This change keeps separate contract coverage for test_support::fs::try_is_file and test_support::fs::inspect_path. It only removes repeated test mechanics. Do not suppress the diagnostic. The refinement is small and improves the test module.

Use this AI coding-agent prompt:

Refactor the duplicate error-propagation tests in PR `#545`.

## File and symbols

File:
- `test_support/src/fs_tests.rs`

Symbols:
- `inspect_path_propagates_errors_other_than_not_found`
- `try_is_file_propagates_errors_other_than_not_found`

## Current validated state

The current codegraph has two tests with the same structure:

1. Create a temporary directory.
2. Write `regular-file`.
3. Query `regular-file/child`.
4. Assert that the operation returns `Err`.
5. Assert that the error kind is not `io::ErrorKind::NotFound`.

The tests differ only in the operation:

- `inspect_path`
- `try_is_file`

Keep both named tests. They document separate public API contracts.

## Required change

In `test_support/src/fs_tests.rs`:

1. Import `std::path::Path`.
2. Add one private helper near `temp_dir`:

```rust
fn assert_traversal_through_file_propagates_non_not_found<T>(
    temp_dir: TempDir,
    inspect: impl FnOnce(&Path) -> io::Result<T>,
) -> anyhow::Result<()> {
    let temp = temp_dir?;
    let file = temp.path().join("regular-file");
    write(&file, b"fixture")?;

    let Err(error) = inspect(&file.join("child")) else {
        anyhow::bail!("traversing through a regular file should fail");
    };
    anyhow::ensure!(
        error.kind() != io::ErrorKind::NotFound,
        "traversal through a file should not be reported as absence, got {error:?}"
    );
    Ok(())
}
```

3. Replace the body of `try_is_file_propagates_errors_other_than_not_found` with:

```rust
assert_traversal_through_file_propagates_non_not_found(temp_dir, try_is_file)
```

4. Replace the body of `inspect_path_propagates_errors_other_than_not_found` with:

```rust
assert_traversal_through_file_propagates_non_not_found(temp_dir, inspect_path)
```

## Constraints

- Do not change `test_support/src/fs.rs`.
- Do not merge the two tests into one parameterized test.
- Do not weaken the assertion about errors other than `NotFound`.
- Do not suppress the CodeScene diagnostic.
- Preserve the existing `#[rstest]` attributes and test names.

## Validation

Run the focused filesystem helper tests. Then run the repository validation required by `AGENTS.md`, including formatting, linting, and tests. Report each command and exit status.

This finding is in scope for PR #545. Do not create a follow-up issue.


🧠 Learnings used
Learnt from: leynos
Repo: leynos/netsuke PR: 0
File: :0-0
Timestamp: 2026-08-12T00:33:17.011Z
Learning: For PR reviews in `leynos/netsuke`, treat warnings as required work. Treat observability, code safety, documentation, and validation coverage as in scope. If required work is out of scope and no existing issue covers it, propose a GitHub follow-up issue.

You are interacting with an AI system.

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.

Replace NamedTempFile::persist with more explicit file creation method

3 participants