Skip to content

change.tests misses coverage through string-keyed tool dispatch #555

Description

@tiendungdev

Summary

change(operation:"tests") reports no covering tests when a test reaches a changed MCP handler through the project's string-keyed tool dispatcher. The tests are real and executable, but the graph loses the registration/invocation hop.

Reproduction

For these changed symbols:

internal/mcp/tools_coding.go::Server.registerCodingTools
internal/mcp/tools_fileops.go::readPhysicalFileEvidence
internal/mcp/tools_fileops.go::Server.handleReadFile

change.tests returned:

coverage_note: 0/3 changed symbols have test coverage
total_files: 0
uncovered: [registerCodingTools, readPhysicalFileEvidence, handleReadFile]

However internal/mcp/read_file_physical_evidence_test.go directly exercises the public tool contract through calls such as:

callTool(t, srv, "read_file", map[string]any{...})

and the focused suite and race suite both pass:

go test ./internal/mcp -run '^TestReadFilePhysicalEvidence' -count=1
go test -race ./internal/mcp -run '^TestReadFilePhysicalEvidence' -count=1

Missing graph path

The runtime path is approximately:

TestReadFilePhysicalEvidence*
  -> callTool(..., "read_file", ...)
  -> tool registry lookup
  -> registration "read_file" -> Server.handleReadFile

A conventional static call graph sees callTool but does not join the string literal to the matching tool registration and handler.

Impact

  • change.tests produces false-negative coverage for MCP handlers;
  • change.contract then warns that no covering tests exist and recommends broader package tests;
  • the same gap applies to routers, RPC dispatchers, command buses, plugin registries, and other string-keyed callback systems.

Suggested feature

Emit dynamic-dispatch test edges by joining:

  1. registration keys to handler symbols, for example "read_file" -> Server.handleReadFile;
  2. test call-site string literals to the same registration key;
  3. the resulting test-to-handler path as an EdgeTests or an explicitly typed dynamic-dispatch edge consumed by change.tests.

Expose provenance so callers can distinguish evidence quality:

{
  "coverage_source": "registry_dispatch",
  "dispatcher": "callTool",
  "registration_key": "read_file",
  "handler": "Server.handleReadFile"
}

Acceptance criteria

  • the physical-evidence tests are returned as targets for Server.handleReadFile;
  • ordinary direct-call test edges remain unchanged;
  • ambiguous or computed registration keys are reported with lower confidence rather than asserted as exact;
  • test fixtures cover direct calls, exact string-key dispatch, aliases, unknown keys, and non-test callers.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions