From ccd748635cf776dc95a1b3bea89298aafe4a2a07 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:00:21 +0800 Subject: [PATCH] test(mcp): retain uncertainty for empty capped IDA reference pages Exercise the empty-but-truncated reference page through trace_feature, preserving unknown coverage without fabricating a reference row. Fixes #2558. --- ...enhancedTools.traceFeatureCoverage.test.ts | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts b/tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts index 8c94d5de05..3b07990b73 100644 --- a/tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts +++ b/tests/boundary/mcp/enhancedTools.traceFeatureCoverage.test.ts @@ -24,6 +24,8 @@ interface Behavior { readonly limitations?: readonly string[]; /** Also report the first string match as a procedure match. */ readonly duplicateProcedure?: boolean; + /** Return no reference rows for this address while preserving cap metadata. */ + readonly emptyXrefsOf?: string; /** Fail the references read of this address. */ readonly failXrefsOf?: string; readonly calls?: string[]; @@ -70,7 +72,9 @@ const provider = (behavior: Behavior = {}): AnalysisOperationPort => ({ const reported = behavior.coverage?.[address]; return ok( createAnalysisExecution( - [address === "0x10" ? "0x20" : "0x21"], + address === behavior.emptyXrefsOf + ? [] + : [address === "0x10" ? "0x20" : "0x21"], PROVIDER, { limitations: behavior.limitations ?? [], @@ -92,6 +96,7 @@ const provider = (behavior: Behavior = {}): AnalysisOperationPort => ({ const expectedTrace = ( residual: readonly string[], extraMatches: readonly object[] = [], + emptyReferenceTargets: readonly string[] = [], ) => ({ query: "hello", search_mode: "literal", @@ -116,7 +121,9 @@ const expectedTrace = ( source_address: "0x20", containing_procedure: containing("0x20"), })), - ], + ].filter( + ({ target_address }) => !emptyReferenceTargets.includes(target_address), + ), truncated: residual.length > 0, residual_unknowns: residual, }); @@ -146,6 +153,19 @@ describe("trace_feature reference coverage", () => { ).toEqual(expectedTrace([unknownFor("0x10")])); }); + it("keeps an empty capped reference page as an unknown, not proof of absence", async () => { + const output = await trace( + provider({ + coverage: { "0x10": true, "0x11": false }, + emptyXrefsOf: "0x10", + }), + ); + + expect(output.normalized_result).toEqual( + expectedTrace([unknownFor("0x10")], [], ["0x10"]), + ); + }); + it("does not carry a truncation over to the next target that reports nothing", async () => { const output = await trace(provider({ coverage: { "0x10": true } }));