fix(uninstall): ignore desktop metadata in the gateway scan - #8457
Conversation
The gateway-directory scan counted any non-directory entry under ~/.nemoclaw/gateways as an unidentified sibling. A .DS_Store, which Finder writes into any directory it shows, was enough to scope the uninstall to the selected gateway. That path skips CLI and shell-shim removal entirely and still exits 0, so nemoclaw, nemohermes, and nemo-deepagents stay on PATH after a run that reported success. Skip regular files whose names are desktop metadata before the conservative non-directory branch. A directory or a symlink wearing one of those names keeps the conservative treatment, and an unrecognized entry still scopes the uninstall, so the guard against hidden gateway state is unchanged. Refs #7905 Signed-off-by: Dongni Yang <dongniy@nvidia.com>
The scan skips only a regular file, so a directory or a symlink carrying a desktop metadata name still scopes the uninstall. Nothing pinned that half of the contract. Add the directory case, and name the concept "desktop metadata" in the comments and test titles so one term covers it. Refs #7905 Signed-off-by: Dongni Yang <dongniy@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughGateway uninstall scanning ignores regular ChangesGateway metadata filtering
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit a8c9939 in the TypeScript / code-coverage/cliThe overall coverage in commit a8c9939 in the Show a code coverage summary of the most impacted files.
Updated |
There was a problem hiding this comment.
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 `@src/lib/actions/uninstall/run-plan-gateway-scan-entries.test.ts`:
- Around line 89-96: Update the uninstall plan tests around runUninstallPlan to
use the real fs.rmSync for the temporary fixture while keeping process and
external-command dependencies mocked. After runUninstallPlan returns, assert
each shim’s actual filesystem state with fs.existsSync(), verifying removed
shims are absent and retained shims remain; remove reliance on the removed array
and rmSync mock-call assertions.
In `@src/lib/actions/uninstall/run-plan.ts`:
- Around line 1657-1659: Update isDesktopMetadataEntry to recognize AppleDouble
files only when the name starts with "._" and contains at least one character
after the prefix, while preserving the existing .DS_Store and .localized
matches. Add regression coverage for .localized, ._name, and the exact ._
boundary.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 67a63897-a12c-4355-9f92-5dcf42cdb030
📒 Files selected for processing (2)
src/lib/actions/uninstall/run-plan-gateway-scan-entries.test.tssrc/lib/actions/uninstall/run-plan.ts
PR Review Advisor — No blocking findings reportedAdvisor assessment: No blocking advisor findings reported Model lanes
Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests. 2 semantic terminology decisionsTerminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.
E2E guidanceAdvisory only. A maintainer can dispatch the default E2E suite against this exact revision. Recommended E2E: None This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
`._` on its own carries no name, so it is not a resource-fork companion and must keep the conservative treatment. Require at least one character after the prefix, and cover `.localized`, `._<name>`, and the bare `._` boundary. Assert the shims through the filesystem rather than the calls a test double recorded: removal now runs the real `rmSync` inside the temporary home, and each case reports which shims survived. Refs #7905 Signed-off-by: Dongni Yang <dongniy@nvidia.com>
|
Both findings were valid and are addressed in 2bf71d0.
Filesystem assertions. Also correct: asserting on the paths an Coverage is now six cases across two tables: Red/green re-proved against the parent source: with One note on the earlier suggestion to share this with |
Refs #7905 Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Addressed the PR Review Advisor warning in the current branch revision ( Validation: focused gateway-scan tests pass 7/7; CLI build and typecheck, Biome, source-shape, test-size, test-title, and Vitest project-overlap checks pass. The completed nine-category security review is clean, and the independent documentation review found no documentation changes needed. The PR description now records both receipts for this revision. |
|
CI follow-up for the current branch revision:
All PR-related tests and required CI are now green. Independent approval remains the merge gate. |
<!-- markdownlint-disable MD041 --> ## Summary Adds the canonical dated changelog entry required before cutting `v0.0.104`. The entry reconciles user-facing changes merged from `v0.0.103` through `8d2b86aaf44968b4f7bc3b714222a73bd28e0403` while excluding hidden and experimental product surfaces. ## Changes - Added `docs/changelog/2026-08-06.mdx` with the exact `## v0.0.104` heading and release themes for local inference, private endpoints, network policy, state authority, lifecycle recovery, uninstall, Hermes, MCP diagnostics, credential safety, and installation guidance. - Source summary links: - [#8399](#8399) -> `docs/changelog/2026-08-06.mdx`: fixed DGX Spark local serving profiles. - [#8418](#8418) -> `docs/changelog/2026-08-06.mdx`: durable llama.cpp lifecycle management. - [#8422](#8422) -> `docs/changelog/2026-08-06.mdx`: recoverable llama.cpp receipt publication. - [#8402](#8402) -> `docs/changelog/2026-08-06.mdx`: remediable DGX Spark storage admission. - [#8391](#8391) -> `docs/changelog/2026-08-06.mdx`: host-local serving recipe contracts. - [#8401](#8401) -> `docs/changelog/2026-08-06.mdx`: serving profile lifecycle provenance. - [#8322](#8322) -> `docs/changelog/2026-08-06.mdx`: guarded llama.cpp route compatibility. - [#8272](#8272) -> `docs/changelog/2026-08-06.mdx`: explicitly trusted private endpoints with stable policy pins and CA trust. - [#8431](#8431) -> `docs/changelog/2026-08-06.mdx`: Personal onboarding policy tier and its trust boundary. - [#8143](#8143) -> `docs/changelog/2026-08-06.mdx`: manifest-derived state authority. - [#7859](#7859) -> `docs/changelog/2026-08-06.mdx`: side-effect-free lifecycle lock timeouts. - [#8262](#8262) -> `docs/changelog/2026-08-06.mdx`: managed gateway lease waiting. - [#8339](#8339) -> `docs/changelog/2026-08-06.mdx`: continued journaled rebuild recreation. - [#8373](#8373) -> `docs/changelog/2026-08-06.mdx`: restore readiness after compatibility decisions. - [#8443](#8443) -> `docs/changelog/2026-08-06.mdx`: fail-closed malformed registry handling. - [#8419](#8419) -> `docs/changelog/2026-08-06.mdx`: bounded recovery for a gateway that never served. - [#8486](#8486) -> `docs/changelog/2026-08-06.mdx`: target-scoped registry recovery. - [#8259](#8259) -> `docs/changelog/2026-08-06.mdx`: scoped uninstall ordering and retry safety. - [#8457](#8457) -> `docs/changelog/2026-08-06.mdx`: desktop metadata exclusion during uninstall. - [#8026](#8026) -> `docs/changelog/2026-08-06.mdx`: typed Hermes configuration policy. - [#8242](#8242) -> `docs/changelog/2026-08-06.mdx`: Hermes WhatsApp session diagnostics. - [#8344](#8344) -> `docs/changelog/2026-08-06.mdx`: patched Hermes image and dependency checks. - [#8491](#8491) -> `docs/changelog/2026-08-06.mdx`: bounded MCP discovery timeout. - [#8490](#8490) -> `docs/changelog/2026-08-06.mdx`: MCP shadow diagnostics. - [#7619](#7619) -> `docs/changelog/2026-08-06.mdx`: web-search credential isolation. - [#8476](#8476) -> `docs/changelog/2026-08-06.mdx`: stable preflight advisory identifiers. - [#8452](#8452) -> `docs/changelog/2026-08-06.mdx`: user-local CLI resolution. - [#8481](#8481) -> `docs/changelog/2026-08-06.mdx`: remote network-policy terminal guidance. - Product-scope exclusions: [#8429](#8429) remains experimental; [#8261](#8261) remains feature-gated; and portable-profile changes [#8408](#8408), [#8415](#8415), [#8446](#8446), [#8458](#8458), [#8462](#8462), and [#8506](#8506) are not promoted as supported product surfaces. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: `npx vitest run test/changelog-docs.test.ts` passed 6/6 and validates dated changelog structure and published links. - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: `docs/changelog/2026-08-06.mdx`; release-range scope, writing rules, documentation style, skip terms, exact names, threat-boundary wording, and published routes reviewed; changelog tests and docs build passed. - Agent: Codex Desktop <!-- docs-review-head-sha: 02b51ae --> <!-- docs-review-agents-blob-sha: c69aad4 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable; no DGX Station host preparation script changed. - Station profile/scenario: Not applicable. - Result: Not applicable. - Supporting evidence: Not applicable. ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run validate:pr` passed after refreshing `origin/main` when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: `npx vitest run test/changelog-docs.test.ts` passed 6/6. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: Not applicable to a single changelog entry. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [x] `npm run docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) The new dated changelog file includes the required parser-safe SPDX header and intentionally has no frontmatter, matching the changelog contract and existing entries. --- Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added release notes for v0.0.104. * Documented fixes for local model runtimes, private endpoints, network policies, state recovery, uninstall behavior, safety updates, MCP diagnostics, credential isolation, and installation guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
The gateway-directory scan counted any non-directory entry under
~/.nemoclaw/gatewaysas an unidentified sibling gateway, which scopes the uninstall to the selected gateway. That path skips CLI and shell-shim removal entirely and still exits 0, sonemoclaw,nemohermes, andnemo-deepagentsstayed on PATH after a run that reported success. A.DS_Store, which macOS writes into a directory it displays, was enough to trigger it. The scan now skips a regular file whose name is desktop metadata.Related Issue
Refs #7905
Changes
src/lib/actions/uninstall/run-plan.ts: addisDesktopMetadataEntryand skip a regular file named.DS_Store,.localized, or._<name>before the conservative non-directory branch indiscoverOtherGatewayEnvironments.entry.isFile()matches, so a directory or a symlink with the same name still setsunidentified, and an unrecognized entry such asnot-a-portstill scopes the uninstall.src/lib/actions/uninstall/run-plan-gateway-scan-entries.test.ts(new): cover the reported metadata-file behavior and guard conservative handling for unidentified entries, the bare._boundary, metadata-named directories, and metadata-named symlinks. A new focused file rather than an addition torun-plan-gateway-segregation.test.ts, which is at 1392 of the 1500-line budget.No new abstraction:
isDesktopMetadataEntryis a single local predicate with one call site.src/lib/build-context.ts:33filters.DS_Storeand._for a different purpose and with a different contract (no symlink conservatism, no.localized), so the two are deliberately not shared.Type of Change
Quality Gates
docs/manage-sandboxes/uninstall-nemoclaw.mdx:88,docs/reference/commands.mdx), and no page ever defined a stray file as a sibling gateway. This makes the code match the documented contract rather than changing a documented surface.rgoverdocs/for "Sibling gateways remain", "shell shims", and ".DS_Store" returns zero hits. Perdocs/CONTRIBUTING.md:83-102a dated changelog entry belongs to the pre-tag release-note PR.a8c993902. The change skips only recognized regular metadata files. Directories, symlinks, malformed names, and unknown entries remain conservative. The nine-category review found no secrets, unsafe input handling, authorization changes, dependency risk, sensitive logging, cryptography changes, insecure configuration, test regressions, or broader security-posture degradation. The added symlink regression strengthens negative coverage for the resource-retention boundary.Documentation Writer Review
no-docs-neededdocs/file changed.DGX Station Hardware Evidence
Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailablenpm run build:cli,npm run typecheck:cli, Biome, source-shape, test-size, test-title, and Vitest project-overlap checks pass.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Scope note
Refs #7905rather thanCloses, because this is very likely not the reporter's cause. Their steps describe a default-port onboard, and~/.nemoclaw/gateways/is only created for a non-default gateway port (src/lib/state/state-root.ts:16), so on that host the directory would not exist and this scan returns early. Reaching this bug needs a host that used a non-default port at some point, leaving the directory behind for a desktop environment to write into.The reporter is on v0.0.97, whose scan lacked the
port === GATEWAY_PORTguard, so the selected gateway counted itself a sibling and took the same retention path. That is #7987, fixed by #7993 and shipped in v0.0.101, after this report. A separate follow-up on the issue asks for the uninstall output to confirm which path they hit.Signed-off-by: Dongni Yang dongniy@nvidia.com
Summary by CodeRabbit
Bug Fixes
Tests