fix(lanes): green the cargo-mutants matrix and repin cosign action - #722
Conversation
sharecli-thermal-tui (140 mutants -> 0 survivors): - per-line connector assertions for append_agent_tree_lines kill the is_last-inversion mutant that a bare contains() cannot distinguish - exclude_re: run_with_pool_status (terminal entry point, same class as run) and the agent_forest_lines <-> <= equivalent sharecli-fuse (255 mutants -> 0 survivors): - platform-correct c01 backend-selection tests (Linux-exact kernel override, macOS-gated mount envelopes) - new tests/c02_intercept_fs.rs (30 tests) covering the no-mount surface: session id, agents.conf, serialize flag, negative-dentry probe/invalidate/meters, read-cache slice/mtime/hit-rate, inode/path mapping, CowMountHandle CoW contract, smoke FUSE configs, provenance, and the EXDEV commit fallback - backend.rs: stable label/diagnostic/runtime-diagnostics tests - fuse mutants.toml: triaged mount-bound class (fuser Reply* is pub(crate); FuseSessionRegistry state needs a live mount; winfsp and mount_smoke are platform/mount-only), cross-platform dead code, and equivalent mutants; documented in docs/ops/mutants-hard-gate.md container-cosign(-soft): repin sigstore/cosign-installer to v3.10.1 (7e8b541) - the v3.7.1 SHA was deleted upstream and could not resolve.
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
Warning Review limit reached
Next review available in: 19 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughSummaryThe PR adds mutation coverage and exclusions for Must Fix
Should Fix
Consider
Request ChangesThe PR should not merge until the oversized test file is split and the resulting test organization is verified with formatting, clippy, workspace tests, and cargo-mutants. WalkthroughThe pull request expands mutation exclusions and FUSE mutation-lane documentation, adds platform-aware FUSE integration coverage, adds thermal TUI unit tests, and updates both cosign installer pins to v3.10.1. ChangesMutation coverage configuration
FUSE backend and integration tests
Thermal TUI test coverage
Cosign action pin updates
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
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. Comment |
| thread::sleep(Duration::from_millis(25)); | ||
| fs::write(&path, b"v2-longer-content").expect("rewrite"); |
There was a problem hiding this comment.
Suggestion: The 25 ms sleep does not guarantee that the filesystem modification time changes before the rewrite. On filesystems with coarser timestamp resolution or delayed metadata updates, read_coalesced can legitimately see the original mtime, serve the cached v1, and fail this test intermittently. Make the test force or verify a distinct mtime rather than relying on a fixed sleep. [possible bug]
Severity Level: Major ⚠️
- ❌ Cache regression test can fail intermittently on coarse-mtime filesystems.
- ⚠️ Cargo test and mutation hard gates become environment-dependent.
- ⚠️ The test may fail to detect stale-cache behavior.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** crates/sharecli-fuse/tests/c02_intercept_fs.rs
**Line:** 376:377
**Comment:**
*Possible Bug: The 25 ms sleep does not guarantee that the filesystem modification time changes before the rewrite. On filesystems with coarser timestamp resolution or delayed metadata updates, `read_coalesced` can legitimately see the original mtime, serve the cached `v1`, and fail this test intermittently. Make the test force or verify a distinct mtime rather than relying on a fixed sleep.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Quality Gate Report❌ Unit Tests: FAILED |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b0203bbce
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| #[test] | ||
| fn c02_empty_session_id_falls_back_to_default() { | ||
| let dir = TempDir::new().expect("tempdir"); | ||
| let fs = InterceptFs::with_options(dir.path(), InterceptFsOptions { session_id: String::new(), ..Default::default() }); |
There was a problem hiding this comment.
In this checkout, cargo +1.95.0 fmt --check reports rustfmt diffs starting in this added test file, including this long InterceptFs::with_options line, and also in the other changed Rust files; since the repo requires the format gate to pass, this commit will fail just fmt-check until it is rustfmt'd.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 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 @.cargo/mutants.toml:
- Around line 16-18: Narrow the exclude_re entry in the mutants configuration so
it matches only the terminal-bound top-level render entry point rather than any
mutant containing “render”. Preserve the event_loop exclusion, and use an
anchored pattern that avoids excluding render-related test helpers or rendered
variables in lib.rs.
In `@crates/sharecli-fuse/mutants.toml`:
- Line 71: Replace the current NegativeDentryCache::is_negative mutant exclusion
with a deterministic boundary test covering an entry whose expiration instant
equals the evaluation time, and assert the entry is treated as expired. If the
implementation cannot inject or control time, document the invariant proving
this equality state is impossible instead.
- Around line 34-39: The mutants.toml classification must not mark the
commit_pending EXDEV guard mutation as equivalent. Update the comment to
describe it as a CI-lane limitation, or add deterministic coverage that
distinguishes EXDEV copy-and-remove fallback from non-EXDEV rename errors
returning WriteSerializeError::Io; retain the existing classifications for the
other listed mutations.
In `@crates/sharecli-fuse/tests/c01_fuse_backend_selection.rs`:
- Around line 24-31: Update the module documentation in
c01_fuse_backend_selection.rs to state that the no-override test runs on Linux
and macOS, asserting FuseBackend::Unavailable on Linux and the documented macOS
behavior on macOS. Add an explicit macOS qualifier to the no-override contract
paragraph, keeping the existing platform descriptions for the mount-error tests
unchanged.
In `@crates/sharecli-fuse/tests/c02_intercept_fs.rs`:
- Around line 3-6: Replace the em dash characters in the doc comments near the
test description and the sections around the per-agent CoW and pending-contract
descriptions with ASCII hyphens, preserving the existing wording and formatting.
- Around line 367-384: Update c02_read_cache_stale_mtime_misses_and_reloads so
the rewritten file is guaranteed to have a different observed mtime before
asserting cache invalidation. Prefer explicitly setting the post-rewrite mtime
and validate that it differs from the initial metadata, or otherwise wait until
metadata reports a changed mtime; keep the existing stale-content and meter
assertions unchanged.
- Around line 521-539: Update
c02_write_serialize_commit_exdev_falls_back_to_copy to create the backing file
using tempfile::NamedTempFile in /dev/shm instead of a process-id-based path.
Use its unique path for staging and commit, and retain explicit cleanup of that
path so failures and rename-based replacement do not leave artifacts.
- Around line 195-217: Update c02_create_rel_stamps_session_provenance to use a
temporary backing location with user.* xattr support, or detect unsupported
xattrs and skip the provenance assertion before expect("stamped"). Preserve the
existing create, cache invalidation, and provenance checks when xattrs are
supported.
- Around line 309-310: Remove the redundant identity map in the helper chain
building names near lines 309-310 of
crates/sharecli-fuse/tests/c02_intercept_fs.rs and collect directly from
by_agent.into_iter(). At lines 449-455 in the same file, likewise remove only
the identity map while preserving the existing filter, then collect directly.
In `@crates/sharecli-thermal-tui/src/lib.rs`:
- Around line 2100-2120: Update test_poll_pool_status_panels_applies_snapshot to
assert the exact PoolOperatorPanel and StatusOperatorPanel values stored in
app.pool_panel and app.status_panel after polling, rather than only checking
that they are Some. Verify the applied fields match the pool and status
snapshots returned by the poll callback.
- Around line 1967-2016: Replace the literal box-drawing characters in the
connector assertions of test_append_agent_tree_lines_last_child_uses_elbow with
equivalent Unicode escape sequences, preserving the runtime checks for the tee
and elbow connectors.
In `@docs/ops/mutants-hard-gate.md`:
- Around line 111-113: Update the coverage summary for c02_intercept_fs.rs to
remove “backend selection,” since that file does not test select_backend()
behavior. Keep backend-selection coverage attributed to
c01_fuse_backend_selection.rs, unless equivalent select_backend() tests are
added to both files.
- Around line 99-101: Update the mutation-scope description in the fuse lane
section to say it covers src except the documented exclusions, rather than
claiming the whole src tree is mutated. Reference
crates/sharecli-fuse/mutants.toml’s exclusions, including src/bin/*,
winfsp_mount.rs, mount_smoke.rs, and exclude_re-selected functions, while
preserving the existing test-suite and triage statements.
🪄 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: 676f4827-3d2a-455e-8ae9-9167ec8bcf1e
📒 Files selected for processing (10)
.cargo/mutants.toml.github/workflows/container-cosign-soft.yml.github/workflows/container-cosign.ymlcrates/sharecli-fuse/mutants.tomlcrates/sharecli-fuse/src/backend.rscrates/sharecli-fuse/src/lib.rscrates/sharecli-fuse/tests/c01_fuse_backend_selection.rscrates/sharecli-fuse/tests/c02_intercept_fs.rscrates/sharecli-thermal-tui/src/lib.rsdocs/ops/mutants-hard-gate.md
📜 Review details
⏰ Context from checks skipped due to timeout. (31)
- GitHub Check: TS/JS
- GitHub Check: OSV / GHSA lockfile scan (required)
- GitHub Check: Rust
- GitHub Check: netblock hermetic (required)
- GitHub Check: Guardrail (nextest)
- GitHub Check: Python
- GitHub Check: Loom (sharecli-sync)
- GitHub Check: Cargo Deny (Advisories + Licenses)
- GitHub Check: chaos restart (required)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Reproducible build (L52)
- GitHub Check: hyperfine healthz (soft)
- GitHub Check: cargo bench (gate)
- GitHub Check: cargo bench (soft)
- GitHub Check: test
- GitHub Check: Lint & Format
- GitHub Check: Offline check after fetch (soft)
- GitHub Check: Dependency Audit
- GitHub Check: SAST Analysis
- GitHub Check: windows_winfsp (windows-latest)
- GitHub Check: live pool probe (soft)
- GitHub Check: dashboard keyboard Tab-cycle
- GitHub Check: linux_native (ubuntu-24.04)
- GitHub Check: coverage
- GitHub Check: dashboard PNG hard diff
- GitHub Check: codeql
- GitHub Check: Unit Tests
- GitHub Check: Mergify Merge Protections
- GitHub Check: Summary
- GitHub Check: windows_winfsp (windows-latest)
- GitHub Check: linux_native (ubuntu-24.04)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Lint / 0_FR reference in PR body.txt: fix(lanes): green the cargo-mutants matrix and repin cosign action
Conclusion: failure
##[group]Run actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
script: const body = context.payload.pull_request.body || "";
const labels = (context.payload.pull_request.labels || []).map((l) => l.name);
const skip =
labels.includes("skip-fr-lint") ||
labels.includes("dependencies") ||
labels.includes("chore");
if (skip) {
core.info("Skipping FR lint due to label: " + labels.join(", "));
return;
}
// Match FR-001, FR-CAST-003, FR-PROC-001 (legacy), etc.
const frPattern = /\bFR-[A-Z0-9]+(?:-[A-Z0-9]+)*\b/;
if (!frPattern.test(body)) {
core.setFailed(
"PR body must reference at least one FR ID (e.g. FR-001). " +
"See FUNCTIONAL_REQUIREMENTS.md / docs/specs/FR.md. " +
"Docs-only chores may use label skip-fr-lint."
);
return;
}
core.info("FR reference found in PR body.");
github-***REDACTED_SECRET_ASSIGNMENT***
debug: false
user-agent: actions/github-script
result-encoding: json
retries: 0
retry-exempt-status-codes: 400,401,403,404,422
##[endgroup]
##[error]PR body must reference at least one FR ID (e.g. FR-001). See FUNCTIONAL_REQUIREMENTS.md / docs/specs/FR.md. Docs-only chores may use label skip-fr-lint.
GitHub Actions: PR Lint / FR reference in PR body: fix(lanes): green the cargo-mutants matrix and repin cosign action
Conclusion: failure
##[group]Run actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
script: const body = context.payload.pull_request.body || "";
const labels = (context.payload.pull_request.labels || []).map((l) => l.name);
const skip =
labels.includes("skip-fr-lint") ||
labels.includes("dependencies") ||
labels.includes("chore");
if (skip) {
core.info("Skipping FR lint due to label: " + labels.join(", "));
return;
}
// Match FR-001, FR-CAST-003, FR-PROC-001 (legacy), etc.
const frPattern = /\bFR-[A-Z0-9]+(?:-[A-Z0-9]+)*\b/;
if (!frPattern.test(body)) {
core.setFailed(
"PR body must reference at least one FR ID (e.g. FR-001). " +
"See FUNCTIONAL_REQUIREMENTS.md / docs/specs/FR.md. " +
"Docs-only chores may use label skip-fr-lint."
);
return;
}
core.info("FR reference found in PR body.");
github-***REDACTED_SECRET_ASSIGNMENT***
debug: false
user-agent: actions/github-script
result-encoding: json
retries: 0
retry-exempt-status-codes: 400,401,403,404,422
##[endgroup]
##[error]PR body must reference at least one FR ID (e.g. FR-001). See FUNCTIONAL_REQUIREMENTS.md / docs/specs/FR.md. Docs-only chores may use label skip-fr-lint.
🧰 Additional context used
📓 Path-based instructions (4)
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Use UTF-8 encoding for all text files; do not use Windows-1252 smart quotes or other special characters.
Use UTF-8 for all text files.
Files:
docs/ops/mutants-hard-gate.mdcrates/sharecli-fuse/mutants.tomlcrates/sharecli-fuse/src/backend.rscrates/sharecli-fuse/src/lib.rscrates/sharecli-fuse/tests/c01_fuse_backend_selection.rscrates/sharecli-fuse/tests/c02_intercept_fs.rscrates/sharecli-thermal-tui/src/lib.rs
**/*.{rs,toml}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,toml}: Use Rust edition 2021 and the pinned toolchain fromrust-toolchain.toml; keep code compatible with the configured stable compiler, rustfmt, and clippy.
Ensure Rust code passes formatting, clippy with-D warnings, and the locked all-features test suite; CI usesRUSTFLAGS=-D warnings.
UsePascalCasefor Rust types,snake_casefor functions, methods, and modules, andSCREAMING_SNAKE_CASEfor constants.
Files:
crates/sharecli-fuse/mutants.tomlcrates/sharecli-fuse/src/backend.rscrates/sharecli-fuse/src/lib.rscrates/sharecli-fuse/tests/c01_fuse_backend_selection.rscrates/sharecli-fuse/tests/c02_intercept_fs.rscrates/sharecli-thermal-tui/src/lib.rs
**/*.rs
📄 CodeRabbit inference engine (CLAUDE.md)
Use Rust for the project and validate Rust changes with Cargo build, Cargo test, and Cargo clippy.
**/*.rs: For new Rust modules, create the test file before the implementation; for bug fixes, write a failing test before the fix; for refactors, ensure existing tests pass before and after.
Use idiomatic, language-appropriate error handling, never useunwraporexpectin production Rust code, and log all errors with structured logging.
Files:
crates/sharecli-fuse/src/backend.rscrates/sharecli-fuse/src/lib.rscrates/sharecli-fuse/tests/c01_fuse_backend_selection.rscrates/sharecli-fuse/tests/c02_intercept_fs.rscrates/sharecli-thermal-tui/src/lib.rs
crates/sharecli-fuse/src/lib.rs
📄 CodeRabbit inference engine (AGENTS.md)
Do not commit rebase or merge conflict markers (
<<<<<<<,=======, or>>>>>>>) incrates/sharecli-fuse/src/lib.rs; the repository pre-commit hook is intended to reject them when enabled.
Files:
crates/sharecli-fuse/src/lib.rs
🪛 GitHub Check: TruffleHog Scan
crates/sharecli-thermal-tui/src/lib.rs
[warning] 1962-1962:
Found verified Lob result 🐷🔑
[warning] 1955-1955:
Found verified Lob result 🐷🔑
[warning] 1877-1877:
Found verified Lob result 🐷🔑
[warning] 1874-1874:
Found verified Lob result with HTML encoding 🐷🔑
[warning] 1959-1959:
Found verified Lob result with HTML encoding 🐷🔑
[warning] 1952-1952:
Found verified Lob result with HTML encoding 🐷🔑
🔇 Additional comments (24)
.github/workflows/container-cosign-soft.yml (1)
36-36: LGTM!.github/workflows/container-cosign.yml (1)
43-43: LGTM!crates/sharecli-thermal-tui/src/lib.rs (9)
1789-1805: LGTM!
1807-1852: LGTM!
1854-1873: LGTM!
1875-1900: LGTM!
1902-1929: LGTM!
1931-1965: LGTM!
2018-2043: LGTM!
2045-2073: LGTM!
2075-2098: LGTM!crates/sharecli-fuse/tests/c02_intercept_fs.rs (5)
1-21: LGTM!
23-66: LGTM!
219-292: LGTM!
386-414: LGTM!
472-519: LGTM!.cargo/mutants.toml (2)
19-20: LGTM!Also applies to: 22-23
13-15: 🎯 Functional CorrectnessNo change needed.
agent_forest_linesusesforest.iter().enumerate()and does not indexforests[i], so the</<=mutant does not create an out-of-bounds extra iteration. The equivalent-equivalence rationale is acceptable for this configuration comment.> Likely an incorrect or invalid review comment.crates/sharecli-fuse/mutants.toml (2)
13-33: LGTM!Also applies to: 40-55, 57-70, 72-72, 74-74
56-56: 🎯 Functional CorrectnessReturn-type exclusion is already correct.
> Likely an incorrect or invalid review comment.docs/ops/mutants-hard-gate.md (1)
97-98: LGTM!Also applies to: 108-110
crates/sharecli-fuse/src/backend.rs (1)
385-391: LGTM!Also applies to: 393-400, 402-410
crates/sharecli-fuse/src/lib.rs (1)
76-77: LGTM!crates/sharecli-fuse/tests/c01_fuse_backend_selection.rs (1)
33-46: LGTM!Also applies to: 128-136, 157-168, 193-199, 232-238
| exclude_re = [ | ||
| "render", | ||
| "event_loop", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
all="$(mktemp)"
filtered="$(mktemp)"
trap 'rm -f "$all" "$filtered"' EXIT
cargo mutants --list --no-config -p sharecli-thermal-tui >"$all"
cargo mutants --list --config .cargo/mutants.toml -p sharecli-thermal-tui >"$filtered"
printf '%s\n' "Unfiltered render-related mutants:"
rg -n 'render|event_loop' "$all"
printf '%s\n' "Filtered render-related mutants:"
rg -n 'render|event_loop' "$filtered"Repository: KooshaPari/sharecli
Length of output: 326
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== mutants config =="
if [ -f .cargo/mutants.toml ]; then
cat -n .cargo/mutants.toml
else
echo "missing .cargo/mutants.toml"
fi
echo
echo "== candidate files =="
git ls-files | rg '(^|/)(mutants\.toml|Cargo\.toml|lib\.rs)$' | sed -n '1,120p'
echo
echo "== occurrences of render/event_loop in selected crate if present =="
python3 - <<'PY'
from pathlib import Path
root = Path('.')
targets = [Path("crates/sharecli-thermal-tui/src/lib.rs"), Path("crates/sharecli-thermal-tui")]
for p in targets:
if p.exists():
print(f"-- {p} --")
text = p.read_text(encoding="utf-8", errors="replace")
lines = text.splitlines()
for i,l in enumerate(lines, 1):
if "render" in l or "event_loop" in l:
print(f"{i}: {l}")
PYRepository: KooshaPari/sharecli
Length of output: 12120
🌐 Web query:
cargo-mutants --list --no-config exclude_re substring matching mutant names
💡 Result:
Use the name-exclusion regex flag: cargo-mutants supports --exclude-re REGEX (short -E) to exclude mutants whose full mutant name matches the given regex [1][2]. The regex is matched against the full mutant name as shown by cargo mutants --list [1][2]. Example (exclude any mutant whose name contains replace ... -> bool): cargo-mutants --list --no-config -E "replace.* -> bool" Notes: - --list only shows which mutants would be generated; it does not run them [3]. - Filters are applied after filename filtering; specifically --re is applied before --exclude-re [1][2]. - You can also set the same option in config as exclude_re = ["..."], and --no-config disables reading the config file [1][4].
Citations:
- 1: https://mutants.rs/filter_mutants.html
- 2: https://crates.io/crates/cargo-mutants/1.2.0
- 3: https://mutants.rs/list.html
- 4: https://mutants.rs/config-file.html
🌐 Web query:
site:crates.io/crates/cargo-mutants mutants.rs filter_mutants Rust Regex substring match
💡 Result:
To filter mutants in cargo-mutants using regex-based substring matching, you can use the built-in filtering options that match against the full name of the mutant [1][2]. The full name of a mutant includes its associated function name, file name, and a description of the mutation; you can view these names by running cargo mutants --list [1][2]. The following command-line flags are available for this purpose: --re REGEX (or -F REGEX): Only test mutants whose full name matches the provided regular expression [1][2]. --exclude-re REGEX (or -E REGEX): Exclude mutants whose full name matches the provided regular expression [1][2]. These options use the regex crate syntax [1] and can be repeated to apply multiple filters. Filters are applied after file-based filtering, and --re is processed before --exclude-re [1]. Since these are regex matches, they function as substring matches by default and can be anchored using ^ and $ [1].
Citations:
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
src = Path("crates/sharecli-thermal-tui/src/lib.rs").read_text(encoding="utf-8", errors="replace")
excludes = re.compile("render")
event_loop_re = re.compile("event_loop")
for m in excludes.finditer(src):
i = m.start()
start_line = src.count("\n", 0, i) + 1
line = src.rsplit("\n", 1)[1] if i <= src.find("\n", src.rfind("\n", 0, i) + 1) else ""
snippet = src[i:].split("\n", 1)[0]
print(f"{start_line}: {repr(snippet)}")
print("\n--- event_loop occurrences ---")
for m in event_loop_re.finditer(src):
i = m.start()
start_line = src.count("\n", 0, i) + 1
print(f"{start_line}: {src[i:].splitlines()[0]}")
PY
echo
echo "== line count =="
wc -l crates/sharecli-thermal-tui/src/lib.rsRepository: KooshaPari/sharecli
Length of output: 7600
Narrow the render mutant exclusion.
exclude_re applies to the full mutant name. The "render" filter excludes every generated mutant whose path, function name, or description contains render, including mutants for test helpers and rendered helper variables in crates/sharecli-thermal-tui/src/lib.rs. Keep exclusions anchored to the terminal-bound functions, such as the top-level render entry point and event_loop, not broad subcomponents.
🤖 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 @.cargo/mutants.toml around lines 16 - 18, Narrow the exclude_re entry in the
mutants configuration so it matches only the terminal-bound top-level render
entry point rather than any mutant containing “render”. Preserve the event_loop
exclusion, and use an anchored pattern that avoids excluding render-related test
helpers or rendered variables in lib.rs.
| # * Equivalent mutants: AgentsConf::empty -> Default (derive Default is the | ||
| # identical pattern set); strip_mount_prefix `<`->`<=` / `==`->`!=` (the | ||
| # guarded branches are unreachable); global_read_cache_meters (documented | ||
| # Default stub); commit_pending EXDEV-guard -> true (the copy fallback is | ||
| # behavior-identical for EXDEV; the widened guard only fires on non-EXDEV | ||
| # rename errors that the CI lane cannot produce). |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
ast-grep outline crates/sharecli-fuse/src \
--items all --type function > /tmp/fuse-functions.txt
rg -n -A60 -B5 'fn commit_pending|raw_os_error|libc_exdev' \
crates/sharecli-fuse/src
cargo mutants --list --no-config -p sharecli-fuse |
rg 'replace match guard|commit_pending|raw_os_error|libc_exdev'Repository: KooshaPari/sharecli
Length of output: 17425
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '--- mutants config snippets ---\n'
sed -n '1,120p' crates/sharecli-fuse/mutants.toml
printf '\n--- EXDEV coverage mentions ---\n'
rg -n -C 6 'EXDEV|libc_exdev|raw_os_error|\b18\b|rename.*fall|cross-device|NoCrossDeviceLink|WriteSerializeError' crates/sharecli-fuse crates 2>/dev/null | head -n 240
printf '\n--- cargo mutants availability ---\n'
command -v cargo-mutants || true
command -v cargo || true
if command -v cargo >/dev/null 2>&1; then
cargo --version
fiRepository: KooshaPari/sharecli
Length of output: 248
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- mutants config snippets ---'
sed -n '1,120p' crates/sharecli-fuse/mutants.toml
printf '%s\n' ''
printf '%s\n' '--- EXDEV coverage mentions ---'
rg -n -C 6 'EXDEV|libc_exdev|raw_os_error|\b18\b|rename.*fall|cross-device|NoCrossDeviceLink|WriteSerializeError' crates/sharecli-fuse crates 2>/dev/null | head -n 240
printf '%s\n' ''
printf '%s\n' '--- cargo mutants availability ---'
command -v cargo-mutants || true
command -v cargo || true
if command -v cargo >/dev/null 2>&1; then
cargo --version
fiRepository: KooshaPari/sharecli
Length of output: 22255
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- c01 tests around EXDEV/cross-device ---'
rg -n -C 10 'EXDEV|cross-device|raw_os_error|18|rename' crates/sharecli-fuse/tests/c01_climb2_fuse.rs crates/sharecli-fuse/src/write_serialize.rs 2>/dev/null || true
printf '%s\n' ''
printf '%s\n' '--- WriteSerializeError ---'
rg -n -C 8 'enum WriteSerializeError|WriteSerializeError::Io' crates/sharecli-fuse/src/write_serialize.rs crates/sharecli-fuse/src 2>/dev/null
printf '%s\n' ''
printf '%s\n' '--- relevant write_serialize unit tests ---'
sed -n '236,290p' crates/sharecli-fuse/src/write_serialize.rsRepository: KooshaPari/sharecli
Length of output: 16498
Do not classify the EXDEV guard mutation as equivalent.
WriteSerialize::commit_pending only falls back to copy+remove when fs::rename returns libc::EXDEV; it returns WriteSerializeError::Io for other rename errors. The existing tests exercise EXDEV and regular errors, but there is no EXDEV cross-device coverage and non-EXDEV fallback is not equivalent. Keep this as an explicit CI-lane limitation or add deterministic coverage.
🤖 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 `@crates/sharecli-fuse/mutants.toml` around lines 34 - 39, The mutants.toml
classification must not mark the commit_pending EXDEV guard mutation as
equivalent. Update the comment to describe it as a CI-lane limitation, or add
deterministic coverage that distinguishes EXDEV copy-and-remove fallback from
non-EXDEV rename errors returning WriteSerializeError::Io; retain the existing
classifications for the other listed mutations.
| "replace AgentsConf::empty -> Self with Default::default()", | ||
| "replace < with <= in strip_mount_prefix", | ||
| "replace == with != in strip_mount_prefix", | ||
| "replace > with >= in NegativeDentryCache::is_negative", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
ast-grep outline crates/sharecli-fuse/src \
--items all --type function > /tmp/fuse-functions.txt
rg -n -A40 -B5 'fn is_negative|NegativeDentryCache' \
crates/sharecli-fuse/srcRepository: KooshaPari/sharecli
Length of output: 24206
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
if command -v cargo >/dev/null 2>&1; then
if ! cargo mutants --help >/dev/null 2>&1; then
echo "cargo-mutants command unavailable"
exit 0
fi
echo "cargo-mutants version:"
cargo mutants --version
echo "mutant list output:"
cargo mutants --list --output-format json 2>/tmp/cargo_mutants_logs.json | \
python3 - <<'PY'
import sys, json
data = json.load(sys.stdin)
for x in data.get("file", []):
name = x.get("name") or ""
if "NegativeDentryCache::is_negative" in name:
print(json.dumps({
"file": x.get("srcfile"),
"line": x.get("line"),
"col": x.get("col"),
"function": x.get("function"),
"name": name,
"replacement": x.get("replacement")
}))
PY
else
echo "cargo command unavailable"
fi
# Behavioral probe for source-level time comparison semantics.
python3 - <<'PY'
expires_at = 100
now_expiring = 100
now_past = 101
for now, label in [(now_expiring, "expired"), (now_past, "past")]:
current_gt = expires_at > now
current_ge = expires_at >= now
changed = current_gt != current_ge
print(f"{label}: expires_at={expires_at} now={now} current_gt={current_gt} current_ge={current_ge} changed={changed}")
PYRepository: KooshaPari/sharecli
Length of output: 191
Add a deterministic boundary test or justify the NegativeDentryCache::is_negative exclusion.
remember_miss() stores Instant::now() + self.ttl, and is_negative() treats expires_at == Instant::now() as expired. The > vs >= change would count an expiring entry as a hit, so document why this state is impossible or add a deterministic boundary test instead of excluding the mutant.
🤖 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 `@crates/sharecli-fuse/mutants.toml` at line 71, Replace the current
NegativeDentryCache::is_negative mutant exclusion with a deterministic boundary
test covering an entry whose expiration instant equals the evaluation time, and
assert the entry is treated as expired. If the implementation cannot inject or
control time, document the invariant proving this equality state is impossible
instead.
| //! | ||
| //! Platform split: the override-handling tests (fskit / kernel / invalid / | ||
| //! deterministic) run on Linux and macOS because `select_backend` honors | ||
| //! `SHARECLI_FUSE_BACKEND` on both. The no-override test and the two | ||
| //! mount-error-envelope tests are macOS-only: on Linux/Windows the backend is | ||
| //! documented as always `Unavailable` (`backend.rs`) and the Linux mount path | ||
| //! goes straight to `fuser::mount` without backend negotiation, so those | ||
| //! assertions cannot hold there. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Align the platform documentation with the test branches.
The module documentation says that the no-override test is macOS-only. The test runs on Linux and asserts FuseBackend::Unavailable there at Line 163 through Line 168. The no-override contract paragraph also needs an explicit macOS qualifier.
Proposed documentation fix
-//! `SHARECLI_FUSE_BACKEND` on both. The no-override test and the two
-//! mount-error-envelope tests are macOS-only: on Linux/Windows the backend is
-//! documented as always `Unavailable` (`backend.rs`) and the Linux mount path
-//! goes straight to `fuser::mount` without backend negotiation, so those
-//! assertions cannot hold there.
+//! `SHARECLI_FUSE_BACKEND` on both. The no-override test runs on both
+//! supported platforms with platform-specific expectations. The two
+//! mount-error-envelope tests are macOS-only because the backend is
+//! documented as `Unavailable` on non-macOS and the Linux mount path goes
+//! straight to `fuser::mount` without backend negotiation.
-/// Backend selection — when no env var is set, `select_backend` returns
+/// On macOS, when no env var is set, `select_backend` returnsAlso applies to: 139-148
🤖 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 `@crates/sharecli-fuse/tests/c01_fuse_backend_selection.rs` around lines 24 -
31, Update the module documentation in c01_fuse_backend_selection.rs to state
that the no-override test runs on Linux and macOS, asserting
FuseBackend::Unavailable on Linux and the documented macOS behavior on macOS.
Add an explicit macOS qualifier to the no-override contract paragraph, keeping
the existing platform descriptions for the mount-error tests unchanged.
| //! C02 — InterceptFs no-mount surfaces: session id, agents.conf, write | ||
| //! serialization flag, negative-dentry probe/invalidate, and the per-agent | ||
| //! CoW stage/commit/discard/pending contract. These are the pure-filesystem | ||
| //! methods that mutation coverage requires; none need a live FUSE mount. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Replace the em dash characters in the doc comments.
Lines 3, 252, and 521 contain — (U+2014). The coding guidelines prohibit special characters in text files. Use - or -- instead.
As per coding guidelines: "Use UTF-8 encoding for all text files; do not use Windows-1252 smart quotes or other special characters."
Also applies to: 252-253, 521-522
🤖 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 `@crates/sharecli-fuse/tests/c02_intercept_fs.rs` around lines 3 - 6, Replace
the em dash characters in the doc comments near the test description and the
sections around the per-agent CoW and pending-contract descriptions with ASCII
hyphens, preserving the existing wording and formatting.
Source: Coding guidelines
| /// Cross-filesystem commit (staging on /tmp, backing on /dev/shm) exercises | ||
| /// the EXDEV copy fallback (mutants hardcoding the EXDEV constant break it). | ||
| #[test] | ||
| fn c02_write_serialize_commit_exdev_falls_back_to_copy() { | ||
| let shm = Path::new("/dev/shm"); | ||
| if !shm.is_dir() { | ||
| eprintln!("skipping EXDEV test: {}/ is not present", shm.display()); | ||
| return; | ||
| } | ||
| let dir = TempDir::new().expect("tempdir"); | ||
| let backing = shm.join(format!("sharecli-exdev-{}", std::process::id())); | ||
| fs::write(&backing, b"seed").expect("seed on tmpfs"); | ||
|
|
||
| let ws = WriteSerialize::with_staging_root(dir.path().join("staging")); | ||
| ws.stage_bytes(&backing, b"staged").expect("stage"); | ||
| ws.commit_pending(&backing).expect("commit across filesystems"); | ||
| assert_eq!(fs::read(&backing).expect("read"), b"staged"); | ||
| let _ = fs::remove_file(&backing); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Use a unique temporary file in /dev/shm and remove it on failure.
Two problems exist in this test.
- The file name uses only the process id.
/dev/shmis shared across the whole machine. A stale file from an earlier run with the same recycled pid, or a parallel run in another container sharing the mount, can collide.TempDirdoes not scope this path. - If an assertion on Line 537 fails, the panic skips Line 538 and leaves the file in
/dev/shm.
Create the backing file with tempfile inside /dev/shm so the path is unique and the handle removes the file on drop.
🛠️ Proposed change
let dir = TempDir::new().expect("tempdir");
- let backing = shm.join(format!("sharecli-exdev-{}", std::process::id()));
- fs::write(&backing, b"seed").expect("seed on tmpfs");
+ let backing_file = tempfile::Builder::new()
+ .prefix("sharecli-exdev-")
+ .tempfile_in(shm)
+ .expect("tmpfs fixture");
+ let backing = backing_file.path().to_path_buf();
+ fs::write(&backing, b"seed").expect("seed on tmpfs");
let ws = WriteSerialize::with_staging_root(dir.path().join("staging"));
ws.stage_bytes(&backing, b"staged").expect("stage");
ws.commit_pending(&backing).expect("commit across filesystems");
assert_eq!(fs::read(&backing).expect("read"), b"staged");
- let _ = fs::remove_file(&backing);Note: commit_pending may replace the file by rename. In that case the NamedTempFile guard no longer owns the inode. Keep the explicit fs::remove_file as a fallback if the rename path applies.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// Cross-filesystem commit (staging on /tmp, backing on /dev/shm) exercises | |
| /// the EXDEV copy fallback (mutants hardcoding the EXDEV constant break it). | |
| #[test] | |
| fn c02_write_serialize_commit_exdev_falls_back_to_copy() { | |
| let shm = Path::new("/dev/shm"); | |
| if !shm.is_dir() { | |
| eprintln!("skipping EXDEV test: {}/ is not present", shm.display()); | |
| return; | |
| } | |
| let dir = TempDir::new().expect("tempdir"); | |
| let backing = shm.join(format!("sharecli-exdev-{}", std::process::id())); | |
| fs::write(&backing, b"seed").expect("seed on tmpfs"); | |
| let ws = WriteSerialize::with_staging_root(dir.path().join("staging")); | |
| ws.stage_bytes(&backing, b"staged").expect("stage"); | |
| ws.commit_pending(&backing).expect("commit across filesystems"); | |
| assert_eq!(fs::read(&backing).expect("read"), b"staged"); | |
| let _ = fs::remove_file(&backing); | |
| } | |
| /// Cross-filesystem commit (staging on /tmp, backing on /dev/shm) exercises | |
| /// the EXDEV copy fallback (mutants hardcoding the EXDEV constant break it). | |
| #[test] | |
| fn c02_write_serialize_commit_exdev_falls_back_to_copy() { | |
| let shm = Path::new("/dev/shm"); | |
| if !shm.is_dir() { | |
| eprintln!("skipping EXDEV test: {}/ is not present", shm.display()); | |
| return; | |
| } | |
| let dir = TempDir::new().expect("tempdir"); | |
| let backing_file = tempfile::Builder::new() | |
| .prefix("sharecli-exdev-") | |
| .tempfile_in(shm) | |
| .expect("tmpfs fixture"); | |
| let backing = backing_file.path().to_path_buf(); | |
| fs::write(&backing, b"seed").expect("seed on tmpfs"); | |
| let ws = WriteSerialize::with_staging_root(dir.path().join("staging")); | |
| ws.stage_bytes(&backing, b"staged").expect("stage"); | |
| ws.commit_pending(&backing).expect("commit across filesystems"); | |
| assert_eq!(fs::read(&backing).expect("read"), b"staged"); | |
| } |
🤖 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 `@crates/sharecli-fuse/tests/c02_intercept_fs.rs` around lines 521 - 539,
Update c02_write_serialize_commit_exdev_falls_back_to_copy to create the backing
file using tempfile::NamedTempFile in /dev/shm instead of a process-id-based
path. Use its unique path for staging and commit, and retain explicit cleanup of
that path so failures and rename-based replacement do not leave artifacts.
| // --- append_agent_tree_lines budget + connectors (C07 L65) --- | ||
| #[test] | ||
| fn test_append_agent_tree_lines_zero_budget_noop() { | ||
| let node = tree_node(100, "claude", Some("claude"), vec![]); | ||
| let mut lines: Vec<Line<'static>> = Vec::new(); | ||
| let mut budget = 0usize; | ||
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | ||
| assert!(lines.is_empty(), "zero budget MUST append nothing"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_append_agent_tree_lines_budget_exhausts_after_root() { | ||
| let node = tree_node( | ||
| 100, | ||
| "claude", | ||
| Some("claude"), | ||
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | ||
| ); | ||
| let mut lines: Vec<Line<'static>> = Vec::new(); | ||
| let mut budget = 1usize; | ||
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | ||
| assert_eq!(lines.len(), 1, "budget 1 MUST stop after the root; got {lines:?}"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_append_agent_tree_lines_last_child_uses_elbow() { | ||
| let node = tree_node( | ||
| 100, | ||
| "claude", | ||
| Some("claude"), | ||
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | ||
| ); | ||
| let mut lines: Vec<Line<'static>> = Vec::new(); | ||
| let mut budget = 3usize; | ||
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | ||
| assert_eq!(lines.len(), 3, "root + two children MUST render; got {lines:?}"); | ||
| // Per-line connector assertions: a bare `contains("└── ")` cannot | ||
| // distinguish an is_last inversion (mutant swaps which child gets the | ||
| // elbow), so pin the connectors by line position. | ||
| assert!( | ||
| lines[1].to_string().contains("├── "), | ||
| "first child MUST use the tee connector; got: {}", | ||
| lines[1] | ||
| ); | ||
| assert!( | ||
| lines[2].to_string().contains("└── "), | ||
| "last child MUST use the elbow connector; got: {}", | ||
| lines[2] | ||
| ); | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Replace literal box-drawing characters.
Lines 2007 and 2012 add special characters directly in the source file. Use Unicode escapes so the test keeps the required runtime value without violating the text-file rule.
Proposed fix
- lines[1].to_string().contains("├── "),
+ lines[1].to_string().contains("\u{251c}\u{2500}\u{2500} "),
...
- lines[2].to_string().contains("└── "),
+ lines[2].to_string().contains("\u{2514}\u{2500}\u{2500} "),As per coding guidelines, do not use Windows-1252 smart quotes or other special characters.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // --- append_agent_tree_lines budget + connectors (C07 L65) --- | |
| #[test] | |
| fn test_append_agent_tree_lines_zero_budget_noop() { | |
| let node = tree_node(100, "claude", Some("claude"), vec![]); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 0usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert!(lines.is_empty(), "zero budget MUST append nothing"); | |
| } | |
| #[test] | |
| fn test_append_agent_tree_lines_budget_exhausts_after_root() { | |
| let node = tree_node( | |
| 100, | |
| "claude", | |
| Some("claude"), | |
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | |
| ); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 1usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert_eq!(lines.len(), 1, "budget 1 MUST stop after the root; got {lines:?}"); | |
| } | |
| #[test] | |
| fn test_append_agent_tree_lines_last_child_uses_elbow() { | |
| let node = tree_node( | |
| 100, | |
| "claude", | |
| Some("claude"), | |
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | |
| ); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 3usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert_eq!(lines.len(), 3, "root + two children MUST render; got {lines:?}"); | |
| // Per-line connector assertions: a bare `contains("└── ")` cannot | |
| // distinguish an is_last inversion (mutant swaps which child gets the | |
| // elbow), so pin the connectors by line position. | |
| assert!( | |
| lines[1].to_string().contains("├── "), | |
| "first child MUST use the tee connector; got: {}", | |
| lines[1] | |
| ); | |
| assert!( | |
| lines[2].to_string().contains("└── "), | |
| "last child MUST use the elbow connector; got: {}", | |
| lines[2] | |
| ); | |
| } | |
| // --- append_agent_tree_lines budget + connectors (C07 L65) --- | |
| #[test] | |
| fn test_append_agent_tree_lines_zero_budget_noop() { | |
| let node = tree_node(100, "claude", Some("claude"), vec![]); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 0usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert!(lines.is_empty(), "zero budget MUST append nothing"); | |
| } | |
| #[test] | |
| fn test_append_agent_tree_lines_budget_exhausts_after_root() { | |
| let node = tree_node( | |
| 100, | |
| "claude", | |
| Some("claude"), | |
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | |
| ); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 1usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert_eq!(lines.len(), 1, "budget 1 MUST stop after the root; got {lines:?}"); | |
| } | |
| #[test] | |
| fn test_append_agent_tree_lines_last_child_uses_elbow() { | |
| let node = tree_node( | |
| 100, | |
| "claude", | |
| Some("claude"), | |
| vec![tree_node(101, "sh", None, vec![]), tree_node(102, "bash", None, vec![])], | |
| ); | |
| let mut lines: Vec<Line<'static>> = Vec::new(); | |
| let mut budget = 3usize; | |
| append_agent_tree_lines(&node, "", true, &HashMap::new(), &HashMap::new(), &mut lines, &mut budget); | |
| assert_eq!(lines.len(), 3, "root + two children MUST render; got {lines:?}"); | |
| // Per-line connector assertions: a bare `contains("└── ")` cannot | |
| // distinguish an is_last inversion (mutant swaps which child gets the | |
| // elbow), so pin the connectors by line position. | |
| assert!( | |
| lines[1].to_string().contains("\u{251c}\u{2500}\u{2500} "), | |
| "first child MUST use the tee connector; got: {}", | |
| lines[1] | |
| ); | |
| assert!( | |
| lines[2].to_string().contains("\u{2514}\u{2500}\u{2500} "), | |
| "last child MUST use the elbow connector; got: {}", | |
| lines[2] | |
| ); | |
| } |
🤖 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 `@crates/sharecli-thermal-tui/src/lib.rs` around lines 1967 - 2016, Replace the
literal box-drawing characters in the connector assertions of
test_append_agent_tree_lines_last_child_uses_elbow with equivalent Unicode
escape sequences, preserving the runtime checks for the tee and elbow
connectors.
Source: Coding guidelines
| // --- poll_pool_status_panels (C07 L65) --- | ||
| #[test] | ||
| fn test_poll_pool_status_panels_applies_snapshot() { | ||
| let mut app = App::new(4); | ||
| let pool = PoolOperatorPanel { | ||
| node_total: 4, | ||
| node_idle: 3, | ||
| bun_total: 2, | ||
| bun_idle: 1, | ||
| max_per_type: 8, | ||
| healthy: false, | ||
| }; | ||
| let status = | ||
| StatusOperatorPanel { scanned: 10, watched: 2, total_processes: 3, agent_rows: 2 }; | ||
| let mut poll: Box<PoolStatusPollFn> = | ||
| Box::new(move || (Some(pool), Some(status))); | ||
| poll_pool_status_panels(&mut app, Some(poll.as_mut())); | ||
| assert!(app.pool_panel.is_some(), "poll MUST apply the pool snapshot"); | ||
| assert!(app.status_panel.is_some(), "poll MUST apply the status snapshot"); | ||
| } | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the returned snapshot values.
Lines 2117 and 2118 only prove that both fields are non-None. The test passes if the callback applies stale or different snapshots. Assert the exact values returned by poll.
Proposed fix
- assert!(app.pool_panel.is_some(), "poll MUST apply the pool snapshot");
- assert!(app.status_panel.is_some(), "poll MUST apply the status snapshot");
+ assert_eq!(app.pool_panel, Some(pool));
+ assert_eq!(app.status_panel, Some(status));🤖 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 `@crates/sharecli-thermal-tui/src/lib.rs` around lines 2100 - 2120, Update
test_poll_pool_status_panels_applies_snapshot to assert the exact
PoolOperatorPanel and StatusOperatorPanel values stored in app.pool_panel and
app.status_panel after polling, rather than only checking that they are Some.
Verify the applied fields match the pool and status snapshots returned by the
poll callback.
| The fuse lane mutates the whole `src/` tree and runs the full package test | ||
| suite (lib + integration). Triage classes beyond the table above, all recorded | ||
| in `crates/sharecli-fuse/mutants.toml`: |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Describe the mutation scope as src except documented exclusions.
The lane does not mutate the whole src/ tree. crates/sharecli-fuse/mutants.toml excludes src/bin/*, winfsp_mount.rs, mount_smoke.rs, and additional functions through exclude_re. Update the wording so that zero survivors are not read as full-source mutation coverage.
Proposed wording
-The fuse lane mutates the whole `src/` tree and runs the full package test
+The fuse lane mutates the `src/` tree except for documented exclusions and runs the full package test📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The fuse lane mutates the whole `src/` tree and runs the full package test | |
| suite (lib + integration). Triage classes beyond the table above, all recorded | |
| in `crates/sharecli-fuse/mutants.toml`: | |
| The fuse lane mutates the `src/` tree except for documented exclusions and runs the full package test | |
| suite (lib + integration). Triage classes beyond the table above, all recorded | |
| in `crates/sharecli-fuse/mutants.toml`: |
🤖 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 `@docs/ops/mutants-hard-gate.md` around lines 99 - 101, Update the
mutation-scope description in the fuse lane section to say it covers src except
the documented exclusions, rather than claiming the whole src tree is mutated.
Reference crates/sharecli-fuse/mutants.toml’s exclusions, including src/bin/*,
winfsp_mount.rs, mount_smoke.rs, and exclude_re-selected functions, while
preserving the existing test-suite and triage statements.
| - **Covered by no-mount tests** — `tests/c02_intercept_fs.rs` exercises the | ||
| InterceptFs no-mount surface (session/CoW/pending/provenance), caches, | ||
| meters, inode/path mapping, backend selection, and the EXDEV commit fallback. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -i 'backend|select|platform|smoke_fuser_config_for_backend' \
crates/sharecli-fuse/tests/c01_fuse_backend_selection.rs \
crates/sharecli-fuse/tests/c02_intercept_fs.rsRepository: KooshaPari/sharecli
Length of output: 13521
Keep backend selection coverage in c01_fuse_backend_selection.rs.
c02_intercept_fs.rs only calls smoke_fuser_config_for_backend(None) for a mount-options assertion, not the select_backend() behavior documented for this exclusion. Move backend-selection coverage to both test files or remove backend selection from the c02_intercept_fs.rs summary.
🤖 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 `@docs/ops/mutants-hard-gate.md` around lines 111 - 113, Update the coverage
summary for c02_intercept_fs.rs to remove “backend selection,” since that file
does not test select_backend() behavior. Keep backend-selection coverage
attributed to c01_fuse_backend_selection.rs, unless equivalent select_backend()
tests are added to both files.
The 04:01 auto-commit daemon edit wrapped the cfg blocks in braces, leaving the Linux block as the function tail. On Linux the if-let becomes the tail expression, so a failed read_dir made the block evaluate to () and the build failed with E0317. Give the Linux block an explicit None tail, matching the macos and fallback blocks.
Quality Gate Report✅ Unit Tests: PASSED |
The ci lint lane runs stable rustfmt (1.96.0) and taplo-cli 0.9.3; the previous edits were formatted with a newer toolchain, producing diffs in crates/sharecli-fuse (backend.rs, c01/c02 tests), sharecli-thermal-tui, and .cargo/mutants.toml. Reformat everything with the CI-pinned tools.
|
Quality Gate Report✅ Unit Tests: PASSED |
| @@ -0,0 +1,543 @@ | |||
| //! FR: FR-003 / FR-009 | |||
There was a problem hiding this comment.
WARNING: c02_intercept_fs.rs is 543 lines, exceeding the 500-line hard limit. Decompose into smaller focused test files (e.g., split by surface: session/CoW, caches/meters, mapping/EXDEV).
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (11 files)
Fix these issues in Kilo Cloud Reviewed by step-3.7-flash · Input: 185K · Output: 50.5K · Cached: 6M |
Recreates the reviewed-and-validated #727 fix (closed without merging) as a fresh change on current main. The Mutation Testing hard gate has been red on every main push since #722: cargo-mutants 27.1.0's new `delete field` mutants bypass exclude_re, leaving 6 survivors in the FuseMountOptions struct literals of the mount entry points. - Extract session_mount_options(session_id) pure helper shared by all four mount entry points; drop the redundant `serialize: true` (already the Default), eliminating the equivalent mutants. - Narrow mutants.toml exclusions to the genuinely mount-bound mount_* entry points (genre-aware regexes) and cover the no-mount registry surface (global, normalize_key, list, resolve_fs, unmount) with the new registry_no_mount_tests module via the shared resolve_entry resolver. - Align CowMountHandle::from_options with the documented contract: derive {backing}/.sharecli-cow when cow, else .sharecli-cow-staging. - resolve_entry single-mount arm is non-panicking (ok_or_else path). Verified: 266 mutants, 228 caught, 38 unviable, 0 missed (cargo-mutants 27.1.0); 51 lib tests; fmt + cargo check clean. FR reference: FR-003 (mutants hard gate), FR-009 (FUSE IO Intercept)
Recreates the reviewed-and-validated #727 fix (closed without merging) as a fresh change on current main. The Mutation Testing hard gate has been red on every main push since #722: cargo-mutants 27.1.0's new `delete field` mutants bypass exclude_re, leaving 6 survivors in the FuseMountOptions struct literals of the mount entry points. - Extract session_mount_options(session_id) pure helper shared by all four mount entry points; drop the redundant `serialize: true` (already the Default), eliminating the equivalent mutants. - Narrow mutants.toml exclusions to the genuinely mount-bound mount_* entry points (genre-aware regexes) and cover the no-mount registry surface (global, normalize_key, list, resolve_fs, unmount) with the new registry_no_mount_tests module via the shared resolve_entry resolver. - Align CowMountHandle::from_options with the documented contract: derive {backing}/.sharecli-cow when cow, else .sharecli-cow-staging. - resolve_entry single-mount arm is non-panicking (ok_or_else path). Verified: 266 mutants, 228 caught, 38 unviable, 0 missed (cargo-mutants 27.1.0); 51 lib tests; fmt + cargo check clean. FR reference: FR-003 (mutants hard gate), FR-009 (FUSE IO Intercept)



Summary
Fixes the last two red hard gates (cargo-mutants thermal + fuse), the broken cosign action pin, and the 04:01 auto-commit daemon's runtime.rs compile break (E0317 on Linux).
cargo-mutants sharecli-thermal-tui — 140 mutants, 0 survivors (was 43)
append_agent_tree_lineselbow test to per-line connector assertions — the surviving mutant inverts which child gets└──, which a barecontains()cannot distinguish.exclude_re:run_with_pool_status(terminal lifecycle entry point, same class asrun) and theagent_forest_lines<→<=equivalent (iis always <leninside the loop).cargo-mutants sharecli-fuse — 255 mutants, 0 survivors (baseline previously failed on the bare runner; then 231 survivors exposed)
backend_select_no_override_picks_kernel_or_fskitis now platform-aware and the mount-envelope tests are macOS-gated; Linux-exact kernel-override assertion added to C01.tests/c02_intercept_fs.rs(30 tests, FR-003/FR-009 annotated) covering the no-mount surface: session id plumbing, agents.conf loading, serialize flag, negative-dentry probe/invalidate/meters, read-cache slice/mtime-guard/hit-rate, inode/path mapping,CowMountHandleCoW stage/commit/discard/pending, smoke FUSE configs, provenance session id, and the cross-filesystem EXDEV commit fallback.backend.rs: stable label/diagnostic/runtime-diagnostics tests.mutants.tomltriage (documented indocs/ops/mutants-hard-gate.md): mount-bound class (fuserReply*constructors arepub(crate),FuseSessionRegistrystate reachable only through a live mount;winfsp_mount.rs/Windows andmount_smoke.rsare platform/mount-only), cross-platform dead code, and equivalent mutants.container-cosign(-soft)
sigstore/cosign-installerto v3.10.1 (7e8b541) — the v3.7.1 SHA was deleted upstream and could not resolve.src/runtime.rs (daemon break)
count_threadscfg arms in braces, leaving the Linux arm as the function tail with a bareif let→ E0317 incargo buildlanes (keyboard, bench). Added the missingNonetail.Verification
cargo mutants -p sharecli-thermal-tui(local, CI parity flags): 133 caught + 7 unviable, exit 0.cargo mutants -p sharecli-fuse(local, CI parity flags): 220 caught + 35 unviable, exit 0.sharecli-fuse+sharecli-thermal-tuitest suites green; clippy clean on changed crates; taplo formatted;cargo check -p sharecligreen with the runtime fix.FR reference: FR-003 (mutants hard gate), FR-009 (FUSE IO Intercept), FR-011 (thermal contention gate).