Skip to content

Cross-repo validation rejects any project that has a coverage shadow row (::missed) #1609

Closed

Description

@vitaliy-shatskiy

Version

codebase-memory-mcp 0.10.2

(measured on 0.10.2; cr_store_has_exact_project is unchanged on main and in v0.10.3 as of 2026-08-14)

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

Cross-repo passes reject perfectly healthy, fully indexed projects — as both source and target — with:

cross-repo source or target project is missing, invalid, or not indexed

cr_store_has_exact_project (src/pipeline/pass_cross_repo.c:123-131) requires the target store's projects table to hold exactly one row for the project. But any project with at least one parse_partial file carries the designed shadow row <name>::missed — the miss-graph that check_index_coverage reads. src/mcp/mcp.c:2414 documents that shadow rows must be ignored by consumers; this code path doesn't.

I expected shadow rows to be filtered here exactly as list_projects already does. This looks like the same bug class as #1044/#1046 (fixed) — a consumer of the projects table that predates the miss-graph and never learned to skip shadows; this is a new site.

Impact measured on a real fleet: 14 of 22 .NET repositories rejected from cross-repo linking. The trigger is chronic for .NET, because stock Visual Studio-generated Dockerfiles produce a permanent parse_partial (#1610), so virtually every .NET repo carries a shadow row at all times. There is no workaround at the tool level: delete_project filters shadow names, and no config key disables the miss-graph — we resorted to deleting the rows with direct SQL, which the next reindex undoes.

Reproduction

  1. Code being indexed — any dummy repo whose root Dockerfile is the stock .NET shape (this alone yields parse_partial, see Dockerfile grammar flags stock .NET Dockerfiles as parse_partial #1610):

    FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "App.dll"]
  2. Index it and confirm the shadow row exists:

    codebase-memory-mcp cli index_repository --repo-path /tmp/demo --mode full
    # store's projects table now holds "demo" AND "demo::missed"
    
  3. Run any cross-repo pass with this project as source or target.

    Result: cross-repo source or target project is missing, invalid, or not indexed.
    Expected: shadow rows ignored (as list_projects does) and the pass runs.

Logs

cross-repo source or target project is missing, invalid, or not indexed

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

  1. vitaliy-shatskiy commented on Aug 14, 2026

    @vitaliy-shatskiy
    Author

    The Dockerfile grammar gap that makes this chronic for .NET fleets is #1610.

  2. DeusData commented on Aug 15, 2026

    @DeusData
    Owner

    Fixed on main in 329cfc3 (merged as 6a701b5, PR #1652). Ships in v0.10.5.

    Thank you for this — your diagnosis was exact, down to the function and the reason. cr_store_has_exact_project required count == 1 over all rows from cbm_store_list_projects, which does not filter the internal <name>::missed miss-graph row that indexing writes into the same database. So any project that had ever recorded a partial parse failed validation as source and as target, and there was nothing the operator could do about it: a partial parse is not something you control, and re-indexing just recreates the row.

    You also pointed at the precedent, and it held up: mcp.c fixed exactly this shape for list_projects in #1044 — "requiring n == 1 over ALL rows made every project with a miss graph vanish". The cross-repo site never learned it. The fix ports that primary-row filter and deliberately keeps the single-primary requirement, which is what proves the database belongs to the project we were asked about rather than being shared or mislabelled; only :: shadow rows stop counting toward it.

    Verified reproduce-first: the new test fails on the previous main with ASSERT(!(result.failed)), passes with the fix, and reverting only the production change brings the identical failure back — so it binds to the fix rather than passing vacuously.

    Your other two reports (#1610, #1611) are triaged as well. #1611 reproduced exactly as you described, both halves. #1610 I could not reproduce — your 3-line Dockerfile, the full stock multi-stage one, and a CRLF variant all index with parse_partial_count: 0 — so I have asked there for the actual file. Given these two verified precisely, I read that as our reproduction missing something rather than the report being wrong.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    parsing/qualityGraph extraction bugs, false positives, missing edgeswindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions