Skip to content

Commit 0b4c208

Browse files
committed
fix: reject relation-only resolve handoffs
Keep live CLI and MCP smoke guidance from treating relation-only group leads as direct actions.\nClarify contradictory availability signals and structurally inapplicable evidence.
1 parent c100bf9 commit 0b4c208

5 files changed

Lines changed: 39 additions & 13 deletions

File tree

docs/implementation/cli-commands.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,14 @@ confidence) or related.
330330
Each target keeps its normalized description, capped at 240 characters, plus
331331
available popularity, repository, license, docs, and code evidence. Positive
332332
docs/code counts render when content is available; otherwise availability is
333-
stated without inventing a count. Available content with a zero count renders
334-
that zero; unavailable content with zero renders `no docs` / `no code`. Missing
335-
licenses/counts produce no placeholder, and structurally inapplicable negatives
336-
are omitted (`no docs` is not shown for repositories and `no code` is not shown
337-
for sites). If availability is false despite a positive recorded count, output
338-
keeps both facts as `docs unavailable (<n> pages recorded)` or
339-
`code unavailable (<n> files recorded)`. A package's
333+
stated without inventing a count unless the backend supplies a contradictory
334+
positive recorded count. Available content with a zero count renders that zero;
335+
unavailable content with zero renders `no docs` / `no code`. Missing
336+
licenses/counts produce no placeholder. Structurally inapplicable evidence
337+
dimensions are omitted entirely: repositories show no docs field and sites show
338+
no code field. If availability is false despite a positive recorded count,
339+
output keeps both facts as `docs unavailable (<n> pages recorded)` or `code
340+
unavailable (<n> files recorded)`. A package's
340341
compact linked-repository fallback appears only when its group does not already
341342
contain the canonical repository target. `targetsTruncated` produces one note
342343
that additional related targets were omitted and direct matches are complete.

scripts/cli-smoke.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ export function assertExperimentalCliResolveText(resolveText: string): void {
10121012
if (directTarget) {
10131013
assert(
10141014
isResolveDirectTargetUnwarned(resolveText, directTarget),
1015-
"experimental direct resolve action should target a listed candidate without a warning",
1015+
"experimental direct resolve action should target a listed direct candidate without a warning",
10161016
);
10171017
return;
10181018
}

scripts/mcp-smoke.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export function assertExperimentalMcpResolveText(
308308
if (directTarget) {
309309
assert(
310310
isResolveDirectTargetUnwarned(resolveTextBody, directTarget),
311-
"experimental direct resolve action should target a listed candidate without a warning",
311+
"experimental direct resolve action should target a listed direct candidate without a warning",
312312
);
313313
return;
314314
}

scripts/resolve-smoke-guidance.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ export function isResolveDirectTargetUnwarned(
1515
const candidateLine = lines[candidateIndex] ?? "";
1616
const nested = candidateLine.startsWith(" ");
1717
if (
18-
nested &&
19-
(candidateLine.includes(" · related ") ||
20-
candidateLine.includes("[related;"))
18+
candidateLine.includes(" · related ") ||
19+
candidateLine.includes("[related;")
2120
) {
2221
return false;
2322
}

scripts/smoke-scripts.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,33 @@ Next: pass the canonical target "github:owner/project" to the next MCP tool.
537537
" github:owner/project [related; repository]",
538538
);
539539
expect(() => assertExperimentalMcpResolveText(relatedMcpAction)).toThrow(
540-
"without a warning",
540+
"listed direct candidate without a warning",
541+
);
542+
543+
const relatedCliLead = relatedCliAction
544+
.replace(
545+
" 1. npm:project [exact] · package",
546+
" 1. github:owner/project · related repository",
547+
)
548+
.replace(
549+
"\n Related:\n github:owner/project · related repository",
550+
"",
551+
);
552+
expect(() => assertExperimentalCliResolveText(relatedCliLead)).toThrow(
553+
"listed direct candidate without a warning",
554+
);
555+
556+
const relatedMcpLead = relatedMcpAction
557+
.replace(
558+
" 1. npm:express [exact; package]",
559+
" 1. github:owner/project [related; repository]\n 2. npm:express [exact; package]",
560+
)
561+
.replace(
562+
"\n Related:\n github:owner/project [related; repository]",
563+
"",
564+
);
565+
expect(() => assertExperimentalMcpResolveText(relatedMcpLead)).toThrow(
566+
"listed direct candidate without a warning",
541567
);
542568
});
543569

0 commit comments

Comments
 (0)