Skip to content

fix(discovery): resolve declaration site paths at manifest load - #73

Merged
pengyuzhang merged 1 commit into
mainfrom
fix/discovery-site-resolution
Aug 24, 2026
Merged

pengyuzhang merged 1 commit into
mainfrom
fix/discovery-site-resolution

Conversation

@pengyuzhang

Copy link
Copy Markdown
Collaborator

What

Thirteen MCP rows name a declaration site and a launch form but carry no path of their own. manifest.load() now fills that path in from the row that does declare one.

Why

The fourteen M-SITE-* rows enumerate the declaration sites and where each lives per OS. The M-PIN-* rows reuse those sites by name, and M-SP-02 deliberately spans two of them via sites rather than site.

Left unresolved, those rows have no location at all — so a runner cannot write them and a scorer cannot match them, for reasons that have nothing to do with the collector under test. On Linux that is the difference between 51 and 64 executable entries.

How

_resolve_sites() builds a site → per-OS path map from the rows that declare one, then fills it into rows that name a site and lack a path. It runs before validate(), so invariant checks see resolved rows.

Two deliberate choices:

  • In the loader, not in each consumer. The runner, the scorer and the synthesizer all need the same answer; resolving once means they cannot disagree about where a declaration lives.
  • Fills gaps only. A row stating its own path keeps it — M-SITE-01 still resolves to ~/.claude.json.

Tests

Five added to test_manifest.py, covering the gap this change opened: every declaration resolves a path somewhere, a pinned row inherits its site's path, a row with its own path keeps it, a multi-site row resolves, and resolution stays per-platform.

$ python3 -m unittest tests.test_manifest
Ran 14 tests in 0.011s
OK

Additive only — no existing line changed, and no dependency beyond the standard library.

Thirteen of the twenty-nine MCP rows name a declaration site and a launch
form but carry no path of their own: the M-PIN entries reuse the sites the
fourteen M-SITE rows enumerate, and M-SP-02 deliberately spans two of them.

Left unresolved, those rows have no location at all, so a runner cannot write
them and a scorer cannot match them -- for reasons that have nothing to do
with the collector under test. On Linux that is the difference between 51 and
64 executable entries.

Resolution happens once at load rather than in each consumer, so the runner,
the scorer and anything else reading the manifest cannot disagree about where
a declaration lives. It fills gaps only: a row stating its own path keeps it.
@pengyuzhang
pengyuzhang force-pushed the fix/discovery-site-resolution branch from 116c7a7 to 76b447e Compare August 23, 2026 18:21
@pengyuzhang
pengyuzhang merged commit 1cb8cf8 into main Aug 24, 2026
8 checks passed
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