Skip to content

fix(mcp): quarantine invalid allowlist entries - #183

Merged
100yenadmin merged 2 commits into
mainfrom
fix/mcp-policy-partial-quarantine
Jul 30, 2026
Merged

fix(mcp): quarantine invalid allowlist entries#183
100yenadmin merged 2 commits into
mainfrom
fix/mcp-policy-partial-quarantine

Conversation

@100yenadmin

Copy link
Copy Markdown
Member

Summary

  • resolve alternate absolute-path spellings only when they identify the same filesystem object as a registered repository
  • quarantine invalid or ambiguous allowlist entries while keeping successfully resolved entries available
  • keep rejected entries denied, surface sanitized degraded diagnostics, and preserve full blocking when no entry resolves or the default is invalid/outside the resolved allowlist
  • update the doctor and operator guardrail for degraded policy state

Closes #182.

Reproduction fixed

The registry stored /Volumes/LEXAR/repos/gitnexus-approved/evaos-hive, while one generated policy used /Volumes/LEXAR/repos/gitnexus-approved/evaOS-Hive. On the case-insensitive macOS volume those paths are the same inode, but electric.8 rejected the entry by string and blocked every Codex MCP repository operation, including NeonDiff.

Validation

  • npx vitest run test/unit/mcp-repository-policy.test.ts test/unit/mcp-config-doctor.test.ts test/unit/doctor-readonly-cli.test.ts — 39 passed
  • npx tsc --noEmit — passed
  • focused ESLint and Prettier checks — passed
  • real registry preflight with valid NeonDiff + invalid typo + case-variant Hive — valid=true, degraded=true, only typo entry rejected
  • built-source MCP proof: list_repos exposed degraded status; NeonDiff and Hive queries succeeded; rejected repo call returned unavailable; startup log did not reveal configured value

Security boundary

This never falls back to unrestricted access. A rejected entry grants no access. A configured allowlist with zero resolved entries remains blocked, and default-repository validation remains blocking.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

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

Next review available in: 38 minutes

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

How can I continue?

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

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

How do review limits work?

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

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

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ef23536-9987-4541-a27c-503fcfa7e979

📥 Commits

Reviewing files that changed from the base of the PR and between 3fa87e1 and 1dad094.

📒 Files selected for processing (4)
  • gitnexus/src/cli/doctor.ts
  • gitnexus/src/mcp/repository-policy.ts
  • gitnexus/test/unit/doctor-readonly-cli.test.ts
  • gitnexus/test/unit/mcp-repository-policy.test.ts
📝 Walkthrough

Priority Level: P3

No actionable P0–P3 issues identified from the provided changes. The implementation appears to preserve valid entries, quarantine rejected entries, maintain fail-closed behavior, sanitize diagnostics, and report degraded policy state.

Walkthrough

MCP allowlist handling now supports degraded policies: invalid or ambiguous entries are quarantined, valid repositories remain available, filesystem aliases can resolve safely, and CLI/server diagnostics report sanitized rejection details. Confidence: 96%.

Changes

MCP repository policy

Layer / File(s) Summary
Allowlist resolution and policy construction
gitnexus/src/mcp/repository-policy.ts
Adds filesystem-identity matching, records per-entry rejections, and returns degraded preflight results while remaining blocked when no entries resolve.
Degraded policy serving
gitnexus/src/mcp/repository-policy.ts
Exposes degraded status in repository listings and tool metadata while preserving access to valid repositories.
Diagnostics and validation
gitnexus/src/cli/..., gitnexus/test/unit/mcp-*.test.ts, GUARDRAILS.md
Updates doctor/MCP warnings, remediation guidance, and coverage for sanitized diagnostics, rejected entries, empty resolution, and filesystem aliases.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant createMcpRepositoryPolicy
  participant FilesystemRegistry
  participant MCPBackend
  MCPClient->>createMcpRepositoryPolicy: Build repository policy
  createMcpRepositoryPolicy->>FilesystemRegistry: Resolve paths and filesystem identities
  FilesystemRegistry-->>createMcpRepositoryPolicy: Valid repositories and rejected entries
  createMcpRepositoryPolicy-->>MCPClient: Degraded or blocked policy
  MCPClient->>MCPBackend: Call tool for resolved repository
  MCPBackend-->>MCPClient: Result or access error
Loading

Possibly related PRs

Suggested labels: P0

Suggested reviewers: azizur100389, magyargergo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main MCP allowlist quarantine change.
Description check ✅ Passed The description matches the MCP allowlist, degraded diagnostics, and blocking behavior changes.
Linked Issues check ✅ Passed [ #182 ] The summarized code and tests cover same-object resolution, quarantined invalid entries, blocking edge cases, and degraded diagnostics.
Out of Scope Changes check ✅ Passed The diff stays on MCP policy, doctor, guards, and tests; no unrelated scope creep is evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 fix/mcp-policy-partial-quarantine

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

@100yenadmin

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
✅ 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 added the P0 Release-blocking priority zero work label Jul 30, 2026
@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

evaOS review status: completed

PR: #183 - fix(mcp): quarantine invalid allowlist entries
Head: 3fa87e14d180b9be7342de615a444b9c16d9a8e9
Updated: 2026-07-30T04:21:44.302Z

evaOS review completed for this PR head.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #183

Review URL: #183 (review)

@evaos-code-review-bot evaos-code-review-bot 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.

Walkthrough

PR: #183 - fix(mcp): quarantine invalid allowlist entries
Head: 3fa87e14d180b9be7342de615a444b9c16d9a8e9 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).

Estimated review effort: 1/5 (~10 min)

Changed Files

File Status Churn Purpose Risk

Review Signal

No validated inline findings.
Dropped findings before posting: 0. High-severity findings: 0.

Risk Taxonomy

No finding categories.

Validation and Proof

1 required validation/proof recommendation(s) selected from changed files.

  • required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
    Proof status: sufficient - PR metadata mentions acceptable proof for each required validation recommendation.
    Profile validation hints: Call out stale index, wrong repo identity, memory growth, and destructive analyze behavior.
    Profile proof expectations: Look for focused CLI, index, query, or migration proof.

Related Context

Related issues/PRs: #182.
Suggested labels: none.
Suggested reviewers: none from current metadata.

Review Settings Preview

  • Profile: assertive
  • Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Suggested labels (suggestion_only); Review status comment (sticky_status)
  • Path instructions: none
  • Label suggestions: gitnexus, code-intelligence, backend
  • Reviewer suggestions: none
  • Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
  • Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks

Pre-merge checklist

  • Inline comments target current RIGHT-side diff lines.
  • No secret-like content survived into posted inline comments.
  • REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
  • Required behavior proof is present or not applicable.
  • Labels and reviewers are suggestions only; the bot did not auto-apply them.

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
gitnexus/src/cli/doctor.ts (1)

279-301: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Confidence: 70%. Degraded MCP policy doesn't set a non-zero exit code.

process.exitCode = 1 is only set if (!report.valid) (Line 299). For the new degraded branch, report.valid is true, so gitnexus doctor --mcp-config (or --json) exits 0 even when entries were rejected. GUARDRAILS.md's new remediation step tells operators to run this command to "repair the named environment key/entry," implying it's meant to be detectable/actionable — but any CI/automation gating on exit code won't notice a degraded policy at all, only a fully blocked one.

🩺 Proposed fix
-    if (!report.valid) process.exitCode = 1;
+    if (!report.valid || report.degraded) process.exitCode = 1;
🤖 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 `@gitnexus/src/cli/doctor.ts` around lines 279 - 301, Update the exit-status
handling in the options.mcpConfig branch of the doctor command so degraded
reports with rejectedEntries also set process.exitCode to 1, including JSON
output. Preserve the existing success status for fully valid, non-degraded
reports and the current failure handling for invalid reports.
🤖 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 `@gitnexus/src/mcp/repository-policy.ts`:
- Around line 114-124: Move filesystem alias resolution out of the synchronous
tool-call path: update resolveRuntimeRepo(), repoForArgs(), and resolveRepo() so
they no longer invoke existingFilesystemIdentity() during request handling.
Prefer precomputing the filesystem alias map during startup and using it for
lookups, or remove the fallback if alias matching is not required; preserve
exact pathKey resolution and ensure runtime repository resolution performs no
synchronous realpathSync.native or statSync calls.

---

Outside diff comments:
In `@gitnexus/src/cli/doctor.ts`:
- Around line 279-301: Update the exit-status handling in the options.mcpConfig
branch of the doctor command so degraded reports with rejectedEntries also set
process.exitCode to 1, including JSON output. Preserve the existing success
status for fully valid, non-degraded reports and the current failure handling
for invalid reports.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6b927a6a-0d28-4efc-91db-aeb2589e8576

📥 Commits

Reviewing files that changed from the base of the PR and between 1c5b2a0 and 3fa87e1.

📒 Files selected for processing (6)
  • GUARDRAILS.md
  • gitnexus/src/cli/doctor.ts
  • gitnexus/src/cli/mcp.ts
  • gitnexus/src/mcp/repository-policy.ts
  • gitnexus/test/unit/mcp-config-doctor.test.ts
  • gitnexus/test/unit/mcp-repository-policy.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (22)
  • GitHub Check: tests / macos-latest (platform-sensitive) 1/3
  • GitHub Check: tests / macos-latest (platform-sensitive) 3/3
  • GitHub Check: tests / windows-latest (platform-sensitive) 3/3
  • GitHub Check: tests / macos-latest (platform-sensitive) 2/3
  • GitHub Check: tests / windows-latest (platform-sensitive) 2/3
  • GitHub Check: tests / ubuntu / coverage 1/3
  • GitHub Check: tests / windows-latest (platform-sensitive) 1/3
  • GitHub Check: tests / ubuntu / coverage 2/3
  • GitHub Check: tests / ubuntu / coverage 3/3
  • GitHub Check: tests / tree-sitter ABI (windows-latest)
  • GitHub Check: tests / tree-sitter ABI (ubuntu-latest)
  • GitHub Check: tests / packaged install smoke (ubuntu-latest)
  • GitHub Check: tests / tree-sitter ABI (macos-latest)
  • GitHub Check: quality / typecheck
  • GitHub Check: tests / benchmarks (GITNEXUS_BENCH)
  • GitHub Check: tests / node floor compat (22.14)
  • GitHub Check: tests / packaged install smoke (windows-latest)
  • GitHub Check: autofix
  • GitHub Check: Build gitnexus
  • GitHub Check: Build gitnexus-web
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (3)
gitnexus/**

📄 CodeRabbit inference engine (.cursor/rules/100-monorepo.mdc)

For CLI (gitnexus/): Run tests with npm test, integration tests with npm run test:integration, and type-check with npx tsc --noEmit

Files:

  • gitnexus/src/cli/mcp.ts
  • gitnexus/test/unit/mcp-config-doctor.test.ts
  • gitnexus/src/cli/doctor.ts
  • gitnexus/test/unit/mcp-repository-policy.test.ts
  • gitnexus/src/mcp/repository-policy.ts
gitnexus/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

gitnexus/**/*.{ts,tsx}: Shared code under gitnexus/src/core/ingestion/ must not name languages; provide language-specific behavior through LanguageProvider/ScopeResolver hooks, implementing and registering ScopeResolver in SCOPE_RESOLVERS.
Before editing any function, class, or method, run GitNexus upstream impact analysis and report the blast radius; warn the user before proceeding when risk is HIGH or CRITICAL.
Use GitNexus query({search_query: ...}) to explore unfamiliar code and context({name: ...}) for complete symbol context instead of grepping.
Never rename symbols with find-and-replace; use GitNexus rename, which understands the call graph.
Follow the configured ESLint rules for TypeScript, React Hooks, and unused imports; run npx eslint . because no lint script is defined.
Use the documented GitNexus architecture and scope-resolution contracts when changing indexing, call-resolution, or inheritance behavior.

Files:

  • gitnexus/src/cli/mcp.ts
  • gitnexus/test/unit/mcp-config-doctor.test.ts
  • gitnexus/src/cli/doctor.ts
  • gitnexus/test/unit/mcp-repository-policy.test.ts
  • gitnexus/src/mcp/repository-policy.ts
gitnexus/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Run CLI/core validation with npm test and npx tsc --noEmit when applicable.

Files:

  • gitnexus/src/cli/mcp.ts
  • gitnexus/test/unit/mcp-config-doctor.test.ts
  • gitnexus/src/cli/doctor.ts
  • gitnexus/test/unit/mcp-repository-policy.test.ts
  • gitnexus/src/mcp/repository-policy.ts
🔇 Additional comments (7)
gitnexus/src/mcp/repository-policy.ts (3)

22-33: LGTM!

Also applies to: 88-90, 176-202


260-297: LGTM!

Also applies to: 352-379


439-469: LGTM!

Also applies to: 494-494, 503-511, 530-537

gitnexus/src/cli/mcp.ts (1)

92-115: LGTM!

GUARDRAILS.md (1)

60-64: LGTM!

gitnexus/test/unit/mcp-config-doctor.test.ts (1)

36-59: LGTM!

Also applies to: 83-83

gitnexus/test/unit/mcp-repository-policy.test.ts (1)

4-6: LGTM!

Also applies to: 176-235, 237-274, 276-309, 380-387

Comment thread gitnexus/src/mcp/repository-policy.ts
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
14954 14891 0 63 21s

✅ All 14891 tests passed

63 test(s) skipped — expand for details

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 81% 56650/69935 N/A% 🟢 ████████████████░░░░
Branches 68.21% 34970/51267 N/A% 🟢 █████████████░░░░░░░
Functions 87.13% 6584/7556 N/A% 🟢 █████████████████░░░
Lines 84.5% 50634/59921 N/A% 🟢 ████████████████░░░░

📋 View full run · Generated by CI

@100yenadmin

Copy link
Copy Markdown
Member Author

Review disposition for the outside-diff doctor finding: fixed in 1dad094. A degraded policy still keeps valid MCP repositories usable, but doctor --mcp-config now exits 1 for both text and JSON modes so automation can detect and repair rejected entries. A CLI regression test proves sanitized output and nonzero status. Focused proof: 40 tests pass; TypeScript, ESLint, and Prettier pass.

@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

evaOS review status: completed

PR: #183 - fix(mcp): quarantine invalid allowlist entries
Head: 1dad0948e8321e50f251dd316a24e4b2f04dd4d0
Updated: 2026-07-30T04:50:12.590Z

evaOS review completed for this PR head.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #183

Review URL: #183 (review)

@evaos-code-review-bot evaos-code-review-bot 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.

Walkthrough

PR: #183 - fix(mcp): quarantine invalid allowlist entries
Head: 1dad0948e8321e50f251dd316a24e4b2f04dd4d0 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).

Estimated review effort: 1/5 (~10 min)

Changed Files

File Status Churn Purpose Risk

Review Signal

No validated inline findings.
Dropped findings before posting: 0. High-severity findings: 0.

Risk Taxonomy

No finding categories.

Validation and Proof

1 required validation/proof recommendation(s) selected from changed files.

  • required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
    Proof status: sufficient - PR metadata mentions acceptable proof for each required validation recommendation.
    Profile validation hints: Call out stale index, wrong repo identity, memory growth, and destructive analyze behavior.
    Profile proof expectations: Look for focused CLI, index, query, or migration proof.

Related Context

Related issues/PRs: #182.
Suggested labels: none.
Suggested reviewers: none from current metadata.

Review Settings Preview

  • Profile: assertive
  • Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Suggested labels (suggestion_only); Review status comment (sticky_status)
  • Path instructions: none
  • Label suggestions: gitnexus, code-intelligence, backend
  • Reviewer suggestions: none
  • Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
  • Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks

Pre-merge checklist

  • Inline comments target current RIGHT-side diff lines.
  • No secret-like content survived into posted inline comments.
  • REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
  • Required behavior proof is present or not applicable.
  • Labels and reviewers are suggestions only; the bot did not auto-apply them.

@100yenadmin
100yenadmin merged commit ea62824 into main Jul 30, 2026
48 checks passed
@100yenadmin
100yenadmin deleted the fix/mcp-policy-partial-quarantine branch July 30, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P0 Release-blocking priority zero work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P0] Quarantine invalid MCP allowlist entries without denying valid repositories

1 participant