refactor(domain): centralize relationship coverage interpretation

This commit is contained in:
morluto 2026-10-14 08:22:07 +08:00
parent e049ef70f7
commit 30128a03cf
3 changed files with 34 additions and 40 deletions

View File

@ -1,3 +1,4 @@
import { relationshipCoverageLimitations } from "./relationshipCoverage.js";
import {
callPathInputSchema,
callPathResultSchema,
@ -240,15 +241,12 @@ const inspectSearch = ({
const coverage = snapshot.evidence.relationship_coverage;
for (const limitation of snapshot.limitations)
limitations.push(limitation);
if (coverage?.status === "partial")
for (const limitation of coverage.limitations)
if (coverage !== null) {
for (const limitation of relationshipCoverageLimitations(coverage))
limitations.push(limitation);
else if (coverage?.status === "unknown")
limitations.push(coverage.reason);
for (const diagnostic of coverage !== null && "diagnostics" in coverage
? coverage.diagnostics
: [])
limitations.push(diagnostic);
for (const diagnostic of coverage.diagnostics ?? [])
limitations.push(diagnostic);
}
// The requested goal is a terminal for this search. Its outgoing edges
// cannot add a path to the goal, so its dossier limits are contextual
// but do not make the searched start-to-goal closure incomplete.

View File

@ -1,4 +1,7 @@
import type { RelationshipCoverage } from "./relationshipCoverage.js";
import {
relationshipCoverageLimitations,
type RelationshipCoverage,
} from "./relationshipCoverage.js";
import type { FunctionDossier } from "./hopperValues.js";
import { uniqueSorted } from "./canonicalOrdering.js";
@ -15,11 +18,7 @@ export const combineFunctionRelationshipCoverage = (
{ direction: "callees" as const, coverage: callees },
];
const diagnostics = uniqueSorted(
reads.flatMap(({ coverage }) =>
coverage !== undefined && "diagnostics" in coverage
? coverage.diagnostics
: [],
),
reads.flatMap(({ coverage }) => coverage?.diagnostics ?? []),
);
const details = diagnostics.length > 0 ? { diagnostics } : {};
const callersLimited = callers?.status !== "complete";
@ -35,15 +34,9 @@ export const combineFunctionRelationshipCoverage = (
const reasons = reads.flatMap(({ direction, coverage }) => {
const label =
direction === "callers" ? callerCoveragePrefix : calleeCoveragePrefix;
const limitations =
coverage === undefined
? ["Provider did not report relationship coverage."]
: coverage.status === "unknown"
? [coverage.reason]
: coverage.status === "partial"
? coverage.limitations
: [];
return limitations.map((reason) => `${label}${reason}`);
return relationshipCoverageLimitations(coverage).map(
(reason) => `${label}${reason}`,
);
});
if (
reads.some(
@ -90,24 +83,11 @@ export const functionCallCoverageLimitations = (
coverage: RelationshipCoverage | null,
dossier: Pick<FunctionDossier, "unresolved_calls">,
): string[] => {
const limitations =
coverage === null
? ["Provider did not report relationship coverage."]
: coverage.status === "unknown"
? [
coverage.reason,
...("diagnostics" in coverage ? coverage.diagnostics : []),
]
: coverage.status === "partial"
? [
...coverage.limitations,
...("diagnostics" in coverage ? coverage.diagnostics : []),
]
: [];
limitations.push(
return uniqueSorted([
...relationshipCoverageLimitations(coverage),
...(coverage?.status === "complete" ? [] : (coverage?.diagnostics ?? [])),
...(dossier.unresolved_calls ?? []).map(
({ address, reason }) => `Unresolved call at ${address}: ${reason}`,
),
);
return uniqueSorted(limitations);
]);
};

View File

@ -33,3 +33,19 @@ export const relationshipCoverageSchema = z.discriminatedUnion("status", [
]);
export type RelationshipCoverage = z.infer<typeof relationshipCoverageSchema>;
/** Reasons the observed relationship inventory cannot establish completeness. */
export const relationshipCoverageLimitations = (
coverage: RelationshipCoverage | null | undefined,
): readonly string[] => {
switch (coverage?.status) {
case undefined:
return ["Provider did not report relationship coverage."];
case "complete":
return [];
case "partial":
return coverage.limitations;
case "unknown":
return [coverage.reason];
}
};