Skip to content

check_index_coverage reports coverage_unavailable for indexed paths when ignored records truncate #1613

Closed

Description

@SunneeYang

Version

codebase-memory-mcp 0.10.2

Platform

macOS (Apple Silicon)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

When discovery sees more than 2,000 deliberately ignored files, coverage metadata records recording_status: "truncated". That global state makes check_index_coverage return coverage_unavailable for an unrelated source file that was successfully indexed, has a current file-hash record, and reports freshness: "metadata_match".

The source remains searchable in the graph; only the by-design not_indexed_file catalogue was truncated. A directory-level .cbmignore is a workaround because it collapses thousands of file rows into one excluded-subtree row, but unrelated indexed code should remain usable without repository-specific asset exclusions.

Current result:

{
  "requested_path": "main.go",
  "status": "coverage_unavailable",
  "freshness": "metadata_match",
  "coverage": []
}

Expected result for that exact, fresh, indexed file:

{
  "requested_path": "main.go",
  "status": "no_recorded_issue",
  "freshness": "metadata_match",
  "coverage": []
}

Explicit partial, skipped, and excluded rows must continue to win. Stale generations, changed/missing file metadata, lookup failures, and truncated empty scope queries must remain coverage_unavailable.

Root cause in coverage_status:

if (!generation_matches || !recording_status ||
    strcmp(recording_status, "complete") != 0) {
    return "coverage_unavailable";
}

This conflates exact-file indexedness/freshness with completeness of the unrelated ignored-file catalogue.

Related: #1356 covers output size/capped counts and documents the .cbmignore workaround. #963/#974 introduced the by-design coverage class and 2,000-entry cap. This report is specifically about the exact-path semantic false negative.

Reproduction

  1. Create a temporary repository with one normal source file:

    package main
    
    func main() {}
  2. Add 2,001 empty files named assets/0001.png through assets/2001.png. Do not add a directory-level .cbmignore.

  3. Run a full index:

    codebase-memory-mcp cli index_repository --repo-path "$PWD" --mode full --name coverage-truncation-repro
  4. Call the MCP tool:

    {
      "project": "coverage-truncation-repro",
      "paths": ["main.go"]
    }
  5. Observe metadata equivalent to:

    {
      "recording_status": "truncated",
      "ignored_files_stored": 2000,
      "ignored_files_total": 2001,
      "hash_records_complete": true,
      "generation_matches": true
    }

    The exact path incorrectly returns coverage_unavailable despite freshness: "metadata_match" and a current file-hash record. It should return no_recorded_issue.

The reproduction uses generated empty image files and a minimal dummy source file; no proprietary code or logs are involved.

Logs


Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

No response

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. DeusData commented on Aug 14, 2026

    @DeusData
    Owner

    Fixed on main by 2235af41 (PR #1617, your own — thank you), merged as 995760b1.

    Your diagnosis was the useful part: the ignored-file catalog going recording_status: "truncated" past 2,000 entries was being treated as proof that every coverage query was unavailable, including exact paths that had a current hash record and freshness: "metadata_match". A global catalog state was standing in for a per-path fact.

    The fix stays conservative in the right places — explicit partial, excluded and skipped records still take precedence, and scope queries plus stale, missing or failed lookups still return coverage_unavailable. An exact path only reports no_recorded_issue when the generation matches, the lookup succeeds, hash records are complete and metadata matches. Loosening exactly one condition and leaving the rest untouched is the right shape for a correctness fix, and the regression test carries the issue number so it will not quietly regress.

    Closing as fixed. It will ship in the next release.

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

    bugSomething isn't workingwindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions