Skip to content

fix(mcp): match fidelity globs with path.Match, not filepath.Match - #647

Open
tiendungdev wants to merge 1 commit into
zzet:mainfrom
tiendungdev:fix/fidelity-glob-slash-matcher
Open

fix(mcp): match fidelity globs with path.Match, not filepath.Match#647
tiendungdev wants to merge 1 commit into
zzet:mainfrom
tiendungdev:fix/fidelity-glob-slash-matcher

Conversation

@tiendungdev

Copy link
Copy Markdown
Contributor

Problem

matchFidelityGlob normalizes both the pattern and the path to forward slashes, then matches with filepath.Match — whose separator is the platform's. On Windows / is an ordinary character to that matcher, so a single * crosses it:

matchFidelityGlob("internal/*.go", "internal/sub/x.go")
  linux/macos -> false
  windows     -> true      <- TestMatchFidelityGlob, fidelity_globs_test.go:61

The file's own doc-comment states the assumption this breaks:

explicit ** support so the documented internal/** / **/*.go forms work as written (Go's filepath.Match never crosses /)

That is true on POSIX, which is exactly why the linux/macos matrix has never been able to see it.

fidelity_globs is a public tool parameter on read_file and get_editing_context, so on Windows a documented internal/*.go rule silently applied its fidelity to the entire subtree beneath internal/.

Change

path.Match / path.Base in matchSegmentGlob. Everything around it already works in slash space — ToSlash on entry, Split(rel, "/"), the ** prefix/suffix handling — so those are the primitives that space calls for. On POSIX they are identical to the filepath versions, since the separator already is /.

Verification

  • TestMatchFidelityGlob red → green on windows/amd64, go1.26.6.
  • Whole internal/mcp package, failing test names diffed against main (c982cf52): newly-broken set empty.

One result I am not claiming

The full-package run came back 27 → 25, but only one of those is mine. TestNotesManager_SaveQueryDelete also flipped to green in that run — and it is not fixed by this change: run in isolation on this very branch it fails 3 times out of 3. It is a pre-existing order/parallelism-dependent flake that happened to pass in that particular full-package run, so the honest attributable delta is one test, not two.

No cross-platform test is possible

path.Match and filepath.Match are the same function on POSIX, so an assertion here passes on linux/macos before and after. The guard belongs in the windows Test native-separator store path comparisons step, whose package list already carries internal/mcp — but I have left ci.yml untouched here because #646 is open against that exact -run line and I would rather not hand you a conflict. Happy to add FidelityGlob to it in a follow-up once #646 lands, or fold it into #646 if you prefer that order.

Related, deliberately not included

internal/mcp/tools_generate_skill.go has the mirror-image inconsistency: matchPathPattern there receives a native rel (filepath.Rel at :134), so its filepath.Match is correct, while :540 tests strings.HasPrefix(rel, prefix+"/") against that same native path. Different bug, different fix, own change.

Branched from main at c982cf52. Windows 11, go1.26.6.

matchFidelityGlob normalizes both the pattern and the path to forward
slashes, then hands them to filepath.Match — whose separator is the
platform's. On Windows '/' is an ordinary character to that matcher, so a
single `*` crosses it:

    matchFidelityGlob("internal/*.go", "internal/sub/x.go")
      = true on windows, false on linux/macos

The file's own doc-comment states the assumption this breaks: "Go's
filepath.Match never crosses `/`". That holds on POSIX and is why the
linux/macos matrix has never seen it.

Everything around it already works in slash space — ToSlash on entry,
Split(rel, "/"), the `**` prefix and suffix handling — so path.Match and
path.Base are the matching primitives that space calls for. Identical to
filepath.Match on POSIX, where the separator already is '/'.

fidelity_globs is a public tool parameter on read_file and
get_editing_context, so on Windows a documented `internal/*.go` rule
silently applied to the whole subtree beneath internal/.

Whole package on windows: TestMatchFidelityGlob flips, newly-broken set
empty.
@zzet

zzet commented Aug 21, 2026

Copy link
Copy Markdown
Owner

@tiendungdev IMO, it will be more beneficial to have a full test suite run for Windows as well as for Linux/MacOS - which is added in the #652 PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants