Skip to content

Commit 02ac470

Browse files
committed
Refine context coverage and diagnostic projections
1 parent 02db1ca commit 02ac470

7 files changed

Lines changed: 68 additions & 5 deletions

File tree

src/context/engine.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,9 @@ function sortOmitted(
11341134
return [...omitted].sort(
11351135
(left, right) =>
11361136
left.tier - right.tier ||
1137+
// A missing card is first coverage; skeleton and hot path are upgrades.
1138+
(left.rung === "card" ? 0 : 1) -
1139+
(right.rung === "card" ? 0 : 1) ||
11371140
left.rank - right.rank ||
11381141
left.symbolId.localeCompare(right.symbolId) ||
11391142
left.rung.localeCompare(right.rung),

src/context/select.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ function compareOmittedPriority(
527527
): number {
528528
return (
529529
left.tier - right.tier ||
530+
// A missing card is first coverage; skeleton and hot path are upgrades.
531+
(left.rung === "card" ? 0 : 1) -
532+
(right.rung === "card" ? 0 : 1) ||
530533
left.rank - right.rank ||
531534
left.symbolId.localeCompare(right.symbolId) ||
532535
left.rung.localeCompare(right.rung)

src/mcp/tools/repo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ export async function handleRepoStatus(
981981
liveIndexStatus,
982982
}
983983
: {}),
984-
memories,
984+
...(memories !== undefined ? { memories } : {}),
985985
derivedState: statusDerivedState,
986986
};
987987
};

src/mcp/tools/search-edit/index.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import { attachRawContext } from "../../token-usage.js";
7+
import { extractProjectionRequestOptions } from "../../request-normalization.js";
78
import { parseActionHandlerArgs } from "../../../gateway/dispatch-spine.js";
89
import {
910
SearchEditRequestSchema,
@@ -102,15 +103,18 @@ function compactStoredSummary(
102103
};
103104
}
104105

105-
function compactRetrievalEvidence(evidence: RetrievalEvidence): RetrievalEvidence {
106+
function compactRetrievalEvidence(
107+
evidence: RetrievalEvidence,
108+
includeDiagnostics: boolean,
109+
): RetrievalEvidence {
106110
const topRanksPerSource = Object.fromEntries(
107111
Object.entries(evidence.topRanksPerSource).map(([source, ranks]) => [
108112
source,
109113
ranks.slice(0, MAX_RETRIEVAL_EVIDENCE_ITEMS),
110114
]),
111115
);
112116

113-
return {
117+
const compacted: RetrievalEvidence = {
114118
...evidence,
115119
topRanksPerSource,
116120
...(evidence.feedbackBoosts
@@ -144,11 +148,17 @@ function compactRetrievalEvidence(evidence: RetrievalEvidence): RetrievalEvidenc
144148
}
145149
: {}),
146150
};
151+
if (!includeDiagnostics) {
152+
delete compacted.fusionLatencyMs;
153+
delete compacted.diagnosticTimings;
154+
}
155+
return compacted;
147156
}
148157

149158
async function handlePreview(
150159
request: Extract<SearchEditRequest, { mode: "preview" }>,
151160
context: ToolContext | undefined,
161+
includeDiagnostics: boolean,
152162
): Promise<SearchEditResponse> {
153163
const preview = await planSearchEditPreview({
154164
repoId: request.repoId,
@@ -199,7 +209,10 @@ async function handlePreview(
199209
expiresAt: new Date(stored.expiresAt).toISOString(),
200210
...(preview.summary.partial ? { partial: true } : {}),
201211
...(preview.retrievalEvidence
202-
? { retrievalEvidence: compactRetrievalEvidence(preview.retrievalEvidence) }
212+
? { retrievalEvidence: compactRetrievalEvidence(
213+
preview.retrievalEvidence,
214+
includeDiagnostics,
215+
) }
203216
: {}),
204217
};
205218
const rawBytes = computeAggregateRawBytes(stored);
@@ -304,9 +317,10 @@ export async function handleSearchEdit(
304317
args: unknown,
305318
context?: ToolContext,
306319
): Promise<SearchEditResponse> {
320+
const { includeDiagnostics = false } = extractProjectionRequestOptions(args);
307321
const request = parseActionHandlerArgs(SearchEditRequestSchema, args);
308322
if (request.mode === "preview") {
309-
return handlePreview(request, context);
323+
return handlePreview(request, context, includeDiagnostics);
310324
}
311325
return handleApply(request);
312326
}

tests/integration/search-edit-tool.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,26 @@ describe("sdl.search.edit", { concurrency: false }, () => {
14161416
hasSources || hasFallback,
14171417
`retrievalEvidence should expose sources or fallbackReason; got ${JSON.stringify(ev)}`,
14181418
);
1419+
assert.strictEqual(ev.fusionLatencyMs, undefined);
1420+
assert.strictEqual(ev.diagnosticTimings, undefined);
1421+
1422+
const diagnosticPreview = (await handleSearchEdit({
1423+
mode: "preview",
1424+
repoId: REPO_ID,
1425+
targeting: "text",
1426+
query: {
1427+
literal: "oldName",
1428+
replacement: "newName",
1429+
global: true,
1430+
},
1431+
editMode: "replacePattern",
1432+
filters: { extensions: [".txt"] },
1433+
includeDiagnostics: true,
1434+
})) as SearchEditPreviewResponse;
1435+
1436+
assert.ok(
1437+
diagnosticPreview.retrievalEvidence?.fusionLatencyMs !== undefined,
1438+
);
14191439
});
14201440

14211441
it("apply rejects an expired planHandle (fail-closed on TTL)", async () => {

tests/unit/context-v2.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,16 @@ describe("ContextEngineV2 pure contracts", () => {
978978
[[rankOne.symbolId, "card"]],
979979
);
980980
assert.equal(result.omitted.byReason.budget, 3);
981+
assert.deepEqual(
982+
result.omitted.highestRanked.map(({ symbolId, rung }) => [symbolId, rung]),
983+
[[rankTwo.symbolId, "card"]],
984+
);
985+
assert.deepEqual(result.nextActions, [
986+
{
987+
id: "symbol.getCard",
988+
args: { symbolIds: [rankTwo.symbolId] },
989+
},
990+
]);
981991
});
982992

983993
it("canonicalizes evidence, edges, lanes, and recovery actions", () => {

tests/unit/repo-status-health.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ describe("repo status health fields", () => {
4141
assert.ok(source.includes("serverInfo: getServerInfo(),"));
4242
});
4343

44+
it("omits memories when repo status has none to surface", () => {
45+
// ponytail: source-adjacent guard until repo status dependencies have injection seams.
46+
const source = readFileSync(
47+
new URL("../../src/mcp/tools/repo.ts", import.meta.url),
48+
"utf8",
49+
);
50+
51+
assert.ok(
52+
source.includes("...(memories !== undefined ? { memories } : {}),"),
53+
);
54+
assert.doesNotMatch(source, /^\s{6}memories,$/m);
55+
});
56+
4457
it("opens and closes the root without enumerating it", async () => {
4558
const root = mkdtempSync(join(tmpdir(), "sdl-root-bounded-probe-"));
4659
let opens = 0;

0 commit comments

Comments
 (0)