refactor(evidence): unify retained inputs across domains (#8299)

Declare logical Evidence sources once and resolve exact retained inputs through
shared application workflows across 20 composition tools. Preserve domain-owned
authentication, source closure, caller choices, coverage and resource admission.

Validation includes public CLI/MCP regressions, local Codex terra/high trials
and fresh-import real-artifact workflows. Measurements, failed attempts and
coverage limits are recorded in docs/verification/evidence-input-composition-2026-10-31.md.

Fixes #8293.
Fixes #8281.

Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
This commit is contained in:
gensokyo-dev authored and GitHub committed 2026-10-31 14:45:21 +00:00
1 parent 23de10bb28
commit a989c0e458
114 files changed
+8532 -1383

No files matched your search

@@ -1,39 +1,39 @@
import type { ExecutionOptions } from "../AnalysisProvider.js";
import {
resolveEvidenceInput,
resolveEvidenceRequest,
type EvidenceLookup,
} from "../EvidenceInputResolver.js";
import { retainedEvidenceReferenceSchema } from "../../domain/evidenceReference.js";
import { parseAnalysisInput } from "../AnalysisInput.js";
import {
compareApplicationVersionsRequestSchema,
compareJavaScriptExportShapesRequestSchema,
compareSourceToBundleCliInputSchema,
compareSourceToBundleRequestSchema,
traceApplicationFeatureRequestSchema,
} from "../../contracts/javascript/applicationWorkflowInputContracts.js";
import type { EvidenceWorkflowExecution } from "../investigation/EvidenceWorkflowExecution.js";
import type { ArtifactResourceScope } from "../../artifacts/ArtifactResourceScope.js";
import type { ResolvedSourceToBundleReference } from "./SourceToBundleReference.js";
import { z } from "zod";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { analysisInputErrorFromIssues } from "../../domain/inputIssueProjection.js";
import { compareJavaScriptApplicationVersions } from "../../domain/javascript/javascriptApplicationVersionComparison.js";
import {
compareApplicationVersionsInputSchema,
applicationVersionIdentitiesSchema,
type ApplicationVersionComparisonResult,
} from "../../domain/javascript/javascriptApplicationVersionComparisonSchemas.js";
import { compareJavaScriptExportShapes } from "../../domain/javascript/javascriptExportShapeComparison.js";
import {
compareJavaScriptExportShapesInputSchema,
javaScriptExportShapeIdentitiesSchema,
type JavaScriptExportShapeComparisonResult,
} from "../../domain/javascript/javascriptExportShapeComparisonSchemas.js";
import { traceApplicationFeature } from "../../domain/javascript/javascriptFeatureTrace.js";
import {
traceApplicationFeatureInputSchema,
applicationTraceIdentitiesSchema,
type ApplicationFeatureTraceResult,
} from "../../domain/javascript/javascriptFeatureTraceSchemas.js";
import { err, ok, type Result } from "../../domain/result.js";
import { compareSourceToBundle } from "../../domain/javascript/sourceToBundleComparison.js";
import {
compareSourceToBundleInputSchema,
type SourceToBundleComparisonResult,
} from "../../domain/javascript/sourceToBundleComparisonSchemas.js";
import type { SourceToBundleComparisonResult } from "../../domain/javascript/sourceToBundleComparisonSchemas.js";
import {
applicationGraphEvidenceInputError,
parseApplicationGraphEvidence,
@@ -48,68 +48,32 @@ import {
} from "./JavaScriptApplicationWorkflowEvidence.js";
/** Completed workflow facts and authenticated sources retained for adapter delivery. */
export interface ApplicationWorkflowExecution<Projection> {
readonly evidence: Evidence;
export interface ApplicationWorkflowExecution<
Projection,
> extends EvidenceWorkflowExecution {
readonly result: Projection;
readonly sources: readonly Evidence[];
}
// Validate the request frame without cloning source payloads before their owner reads them.
const featureTraceFrameSchema = z.strictObject({
...traceApplicationFeatureInputSchema.shape,
application: z.unknown().nonoptional(),
native_observations: z.array(z.unknown()).default([]),
});
const versionComparisonFrameSchema = z.strictObject({
...compareApplicationVersionsInputSchema.shape,
left: z.unknown().nonoptional(),
right: z.unknown().nonoptional(),
left_native_observations: z.array(z.unknown()).default([]),
right_native_observations: z.array(z.unknown()).default([]),
});
const exportShapeFrameSchema = z.strictObject({
...compareJavaScriptExportShapesInputSchema.shape,
left: z.unknown().nonoptional(),
right: z.unknown().nonoptional(),
});
const resolveWorkflowEvidence = (
raw: unknown,
lookup: EvidenceLookup | undefined,
): Result<unknown, AnalysisError> => {
const reference = retainedEvidenceReferenceSchema.safeParse(raw);
return reference.success
? resolveEvidenceInput(reference.data, lookup)
: ok(raw);
};
/** Resolve both selections before authenticating either graph, retaining diagnostic inputs. */
const resolveApplicationGraphPair = (
/** Authenticate the resolved graph pair at the owning domain boundary. */
const parseApplicationGraphPair = (
operation: string,
input: { readonly left: unknown; readonly right: unknown },
lookup: EvidenceLookup | undefined,
): Result<
{
readonly left: ApplicationGraphEvidenceSource;
readonly right: ApplicationGraphEvidenceSource;
readonly selected: { readonly left: unknown; readonly right: unknown };
},
AnalysisError
> => {
const selectedLeft = resolveWorkflowEvidence(input.left, lookup);
if (!selectedLeft.ok) return selectedLeft;
const selectedRight = resolveWorkflowEvidence(input.right, lookup);
if (!selectedRight.ok) return selectedRight;
const left = parseApplicationGraphEvidence(selectedLeft.value, ["left"]);
const left = parseApplicationGraphEvidence(input.left, ["left"]);
if (!left.ok)
return err(applicationGraphEvidenceInputError(operation, left.error));
const right = parseApplicationGraphEvidence(selectedRight.value, ["right"]);
const right = parseApplicationGraphEvidence(input.right, ["right"]);
if (!right.ok)
return err(applicationGraphEvidenceInputError(operation, right.error));
return ok({
left: left.value,
right: right.value,
selected: { left: selectedLeft.value, right: selectedRight.value },
});
};
@@ -117,20 +81,21 @@ const resolveApplicationGraphPair = (
export const traceApplicationFeatureEvidence = (
rawInput: unknown,
lookup?: EvidenceLookup,
options: Pick<ExecutionOptions, "signal"> = {},
): Result<
ApplicationWorkflowExecution<ApplicationFeatureTraceResult>,
AnalysisError
> => {
const operation = "trace_application_feature";
const request = parseAnalysisInput(
const request = resolveEvidenceRequest(
operation,
rawInput,
featureTraceFrameSchema,
traceApplicationFeatureRequestSchema,
lookup,
options,
);
if (!request.ok) return request;
const selected = resolveWorkflowEvidence(request.value.application, lookup);
if (!selected.ok) return selected;
const input = { ...request.value, application: selected.value };
const input = request.value.input;
const sourceResult = parseApplicationGraphEvidence(input.application, [
"application",
]);
@@ -189,21 +154,24 @@ export const traceApplicationFeatureEvidence = (
export const compareApplicationVersionsEvidence = (
rawInput: unknown,
lookup?: EvidenceLookup,
options: Pick<ExecutionOptions, "signal"> = {},
): Result<
ApplicationWorkflowExecution<ApplicationVersionComparisonResult>,
AnalysisError
> => {
const operation = "compare_application_versions";
const request = parseAnalysisInput(
const request = resolveEvidenceRequest(
operation,
rawInput,
versionComparisonFrameSchema,
compareApplicationVersionsRequestSchema,
lookup,
options,
);
if (!request.ok) return request;
const pair = resolveApplicationGraphPair(operation, request.value, lookup);
const input = request.value.input;
const pair = parseApplicationGraphPair(operation, input);
if (!pair.ok) return pair;
const { left, right } = pair.value;
const input = { ...request.value, ...pair.value.selected };
const leftNativeResult = parseNativeApplicationEvidence(
input.left_native_observations,
["left_native_observations"],
@@ -262,10 +230,47 @@ export const compareApplicationVersionsEvidence = (
});
};
/** Compare source and bundle inputs already parsed by a trusted adapter. */
export const compareSourceToBundleEvidence = (
input: ResolvedSourceToBundleReference &
Pick<z.output<typeof compareSourceToBundleInputSchema>, "application">,
/** Select the application record and historical graph through their shared owners. */
export const executeSourceToBundleComparison = async (
rawInput: unknown,
schema:
| typeof compareSourceToBundleCliInputSchema
| typeof compareSourceToBundleRequestSchema,
lookup: EvidenceLookup | undefined,
resources: ArtifactResourceScope,
options: Pick<ExecutionOptions, "signal"> = {},
): Promise<
Result<
ApplicationWorkflowExecution<SourceToBundleComparisonResult>,
AnalysisError
>
> => {
const selected = resolveEvidenceRequest(
"compare_source_to_bundle",
rawInput,
schema,
lookup,
options,
);
if (!selected.ok) return selected;
const { resolveSourceToBundleReference } =
await import("./SourceToBundleReference.js");
const reference = await resolveSourceToBundleReference(
selected.value.input.reference,
options.signal,
resources,
);
return reference.ok
? compareSourceToBundleEvidence({
...reference.value,
application: selected.value.input.application,
})
: reference;
};
/** Compare an owner-parsed historical graph with an unadmitted application source. */
const compareSourceToBundleEvidence = (
input: ResolvedSourceToBundleReference & { readonly application: unknown },
): Result<
ApplicationWorkflowExecution<SourceToBundleComparisonResult>,
AnalysisError
@@ -307,21 +312,24 @@ export const compareSourceToBundleEvidence = (
export const compareJavaScriptExportShapesEvidence = (
rawInput: unknown,
lookup?: EvidenceLookup,
options: Pick<ExecutionOptions, "signal"> = {},
): Result<
ApplicationWorkflowExecution<JavaScriptExportShapeComparisonResult>,
AnalysisError
> => {
const operation = "compare_javascript_export_shapes";
const request = parseAnalysisInput(
const request = resolveEvidenceRequest(
operation,
rawInput,
exportShapeFrameSchema,
compareJavaScriptExportShapesRequestSchema,
lookup,
options,
);
if (!request.ok) return request;
const pair = resolveApplicationGraphPair(operation, request.value, lookup);
const input = request.value.input;
const pair = parseApplicationGraphPair(operation, input);
if (!pair.ok) return pair;
const { left, right } = pair.value;
const input = { ...request.value, ...pair.value.selected };
const identities = javaScriptExportShapeIdentitiesSchema.safeParse({
left: left.evidence,
right: right.evidence,
@@ -0,0 +1,195 @@
import { expect, it, vi } from "vitest";
import { createEvidence, type Evidence } from "../../domain/evidence.js";
import {
JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE,
JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
} from "../../contracts/javascript/javascriptApplicationWorkflowExamples.js";
import { JAVASCRIPT_EXPORT_SHAPE_COMPARISON_EXAMPLE } from "../../contracts/javascript/javascriptExportShapeComparisonExample.js";
import { JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE } from "../../contracts/javascript/javascriptRuntimeReconciliationExample.js";
import {
compareApplicationVersionsEvidence,
compareJavaScriptExportShapesEvidence,
traceApplicationFeatureEvidence,
} from "./JavaScriptApplicationWorkflowService.js";
import { reconcileJavaScriptRuntimeEvidence } from "./JavaScriptRuntimeReconciliationService.js";
import { traceJavaScriptSemanticsEvidence } from "./JavaScriptSemanticTraceService.js";
const reference = ({ evidence_id }: Evidence) => ({
kind: "retained-evidence" as const,
evidence_id,
});
const native = createEvidence(
{ path: "/example/addon.node", sha256: "e".repeat(64), format: "elf" },
{ id: "fixture", name: "Native fixture", version: "1" },
{ operation: "procedure_info", parameters: {}, result: {} },
);
it("resolves feature native arrays without changing source identity or unknowns", () => {
const input = {
...JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
native_observations: [native],
};
const inline = traceApplicationFeatureEvidence(input);
const records = new Map(
[input.application, native].map((record) => [record.evidence_id, record]),
);
const lookup = vi.fn((id: string) => records.get(id));
const retained = traceApplicationFeatureEvidence(
{
...input,
application: reference(input.application),
native_observations: [reference(native)],
},
lookup,
);
if (!inline.ok) throw inline.error;
if (!retained.ok) throw retained.error;
expect(retained.value.evidence.evidence_id).toBe(
inline.value.evidence.evidence_id,
);
expect(retained.value.result).toEqual(inline.value.result);
expect(retained.value.sources.map(({ evidence_id }) => evidence_id)).toEqual([
input.application.evidence_id,
native.evidence_id,
]);
expect(lookup).toHaveBeenCalledTimes(2);
});
it("resolves per-side native observations with one lookup per repeated exact ID", () => {
const input = {
...JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE,
left_native_observations: [native],
right_native_observations: [native],
};
const inline = compareApplicationVersionsEvidence(input);
const records = new Map(
[input.left, input.right, native].map((record) => [
record.evidence_id,
record,
]),
);
const lookup = vi.fn((id: string) => records.get(id));
const retained = compareApplicationVersionsEvidence(
{
left: reference(input.left),
right: reference(input.right),
left_native_observations: [reference(native)],
right_native_observations: [reference(native)],
},
lookup,
);
if (!inline.ok) throw inline.error;
if (!retained.ok) throw retained.error;
expect(retained.value.evidence.evidence_id).toBe(
inline.value.evidence.evidence_id,
);
expect(retained.value.result).toEqual(inline.value.result);
expect(lookup).toHaveBeenCalledTimes(3);
});
it("uses retained graphs for exact export-shape comparison", () => {
const input = JAVASCRIPT_EXPORT_SHAPE_COMPARISON_EXAMPLE;
const inline = compareJavaScriptExportShapesEvidence(input);
const records = new Map(
[input.left, input.right].map((record) => [record.evidence_id, record]),
);
const retained = compareJavaScriptExportShapesEvidence(
{
...input,
left: reference(input.left),
right: reference(input.right),
},
(id) => records.get(id),
);
if (!inline.ok) throw inline.error;
if (!retained.ok) throw retained.error;
expect(retained.value.evidence.evidence_id).toBe(
inline.value.evidence.evidence_id,
);
});
it("resolves nested static layers and runtime arrays before source-owned reconciliation", () => {
const input = JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE;
const records = new Map(
[
...input.static_layers.map(({ analysis }) => analysis),
...input.runtime_observations,
].map((record) => [record.evidence_id, record]),
);
const inline = reconcileJavaScriptRuntimeEvidence(input);
const retained = reconcileJavaScriptRuntimeEvidence(
{
...input,
static_layers: input.static_layers.map((layer) => ({
...layer,
analysis: reference(layer.analysis),
})),
runtime_observations: input.runtime_observations.map(reference),
},
(id) => records.get(id),
);
if (!inline.ok) throw inline.error;
if (!retained.ok) throw retained.error;
expect(retained.value.evidence.evidence_id).toBe(
inline.value.evidence.evidence_id,
);
expect(
retained.value.sources.map(({ evidence_id }) => evidence_id).sort(),
).toEqual([...records.keys()].sort());
});
it("preserves semantic-trace unknown coverage through retained sources", () => {
const application = JAVASCRIPT_FEATURE_TRACE_EXAMPLE.application;
const input = {
application,
query: {
seed: { kind: "property", name: "unobserved" },
direction: "ownership",
},
};
const inline = traceJavaScriptSemanticsEvidence(input);
const retained = traceJavaScriptSemanticsEvidence(
{ ...input, application: reference(application) },
(id) => (id === application.evidence_id ? application : undefined),
);
if (!inline.ok) throw inline.error;
if (!retained.ok) throw retained.error;
expect(retained.value.result).toEqual(inline.value.result);
expect(retained.value.sources).toEqual([application]);
});
it("reports missing nested references before reconciliation without guessing a source", () => {
const layer = JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE.static_layers[0];
if (layer === undefined) throw new Error("Expected an application layer");
const result = reconcileJavaScriptRuntimeEvidence({
...JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE,
static_layers: [{ ...layer, analysis: reference(layer.analysis) }],
});
expect(result).toMatchObject({
ok: false,
error: { _tag: "EvidenceIntegrityError" },
});
});
it("honors cancellation before reading any retained graph", () => {
const controller = new AbortController();
const reason = { request: "cancel before source resolution" };
controller.abort(reason);
const application = JAVASCRIPT_FEATURE_TRACE_EXAMPLE.application;
const lookup = vi.fn(() => application);
const result = traceApplicationFeatureEvidence(
{
...JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
application: reference(application),
},
lookup,
{ signal: controller.signal },
);
expect(result).toMatchObject({
ok: false,
error: { _tag: "AnalysisCancelledError", cause: reason },
});
expect(lookup).not.toHaveBeenCalled();
});
@@ -1,14 +1,21 @@
import type { ExecutionOptions } from "../AnalysisProvider.js";
import { resolve } from "node:path";
import { z } from "zod";
import type { z } from "zod";
import {
resolveEvidenceRequest,
type EvidenceLookup,
} from "../EvidenceInputResolver.js";
import type { EvidenceWorkflowExecution } from "../investigation/EvidenceWorkflowExecution.js";
import type { EvidenceRequestFrameInput } from "../../domain/evidenceInputContract.js";
import { reconcileJavaScriptRuntimeRequestSchema } from "../../contracts/javascript/applicationWorkflowInputContracts.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import type { Evidence } from "../../domain/evidence.js";
import { analysisInputErrorFromIssues } from "../../domain/inputIssueProjection.js";
import {
readRuntimeReconciliationInput,
reconcileJavaScriptRuntime,
} from "../../domain/javascript/javascriptRuntimeReconciliation.js";
import { reconcileJavaScriptRuntimeInputSchema } from "../../domain/javascript/javascriptRuntimeReconciliationSchemas.js";
import { runtimeReconciliationIdentitiesSchema } from "../../domain/javascript/javascriptRuntimeReconciliationSchemas.js";
import { err, ok, type Result } from "../../domain/result.js";
import { createJavaScriptRuntimeReconciliationEvidence } from "./JavaScriptRuntimeReconciliationEvidence.js";
@@ -17,32 +24,56 @@ const OPERATION = "reconcile_javascript_runtime" as const;
/** Derive a combined JAG from verified static and passive-runtime Evidence. */
export const reconcileJavaScriptRuntimeEvidence = (
rawInput: unknown,
): Result<Evidence, AnalysisError> => {
const parsed = reconcileJavaScriptRuntimeInputSchema.safeParse(rawInput);
if (!parsed.success)
return err(
analysisInputErrorFromIssues(OPERATION, parsed.error.issues, rawInput),
);
return reconcileJavaScriptRuntimeEvidenceValidated(parsed.data);
};
/** Reconcile input already parsed by a trusted adapter boundary. */
export const reconcileJavaScriptRuntimeEvidenceValidated = (
parsedInput: z.output<typeof reconcileJavaScriptRuntimeInputSchema>,
): Result<Evidence, AnalysisError> => {
lookup?: EvidenceLookup,
options: Pick<ExecutionOptions, "signal"> = {},
): Result<EvidenceWorkflowExecution, AnalysisError> => {
const selected = resolveEvidenceRequest(
OPERATION,
rawInput,
reconcileJavaScriptRuntimeRequestSchema,
lookup,
options,
);
if (!selected.ok) return selected;
const parsed = readRuntimeReconciliationInput(
normalizeRuntimeMappingRoots(parsedInput),
normalizeRuntimeMappingRoots(selected.value.input),
);
if (!parsed.ok) return parsed;
const identities = runtimeReconciliationIdentitiesSchema.safeParse({
static_layers: parsed.value.layers.map(({ role, evidence }) => ({
role,
analysis: evidence,
})),
runtime_observations: parsed.value.captures.map(({ evidence }) => evidence),
});
if (!identities.success)
return err(
analysisInputErrorFromIssues(
OPERATION,
identities.error.issues,
rawInput,
),
);
const result = reconcileJavaScriptRuntime(parsed.value);
return ok(
createJavaScriptRuntimeReconciliationEvidence(parsed.value.input, result),
);
return ok({
evidence: createJavaScriptRuntimeReconciliationEvidence(
parsed.value.input,
result,
),
sources: [
...parsed.value.layers.map(({ evidence }) => evidence),
...parsed.value.captures.map(({ evidence }) => evidence),
],
});
};
type RuntimeReconciliationFrame = EvidenceRequestFrameInput<
z.output<typeof reconcileJavaScriptRuntimeRequestSchema>
>;
const normalizeRuntimeMappingRoots = (
input: z.output<typeof reconcileJavaScriptRuntimeInputSchema>,
): z.output<typeof reconcileJavaScriptRuntimeInputSchema> => ({
input: RuntimeReconciliationFrame,
): RuntimeReconciliationFrame => ({
...input,
static_layers: input.static_layers.map((layer) => ({
...layer,
@@ -1,26 +1,41 @@
import { z } from "zod";
import type { ExecutionOptions } from "../AnalysisProvider.js";
import {
resolveEvidenceRequest,
type EvidenceLookup,
} from "../EvidenceInputResolver.js";
import { traceJavaScriptSemanticsRequestSchema } from "../../contracts/javascript/applicationWorkflowInputContracts.js";
import { AnalysisInputError } from "../../domain/analysisErrorCore.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import {
applicationGraphEvidenceInputError,
parseApplicationGraphEvidence,
} from "./JavaScriptApplicationEvidenceGraph.js";
import type { Evidence } from "../../domain/evidence.js";
import { queryJavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticQuery.js";
import {
traceJavaScriptSemanticsInputSchema,
type JavaScriptSemanticTraceResult,
} from "../../domain/javascript/javascriptSemanticTraceSchemas.js";
import type { JavaScriptSemanticTraceResult } from "../../domain/javascript/javascriptSemanticTraceSchemas.js";
import { err, ok, type Result } from "../../domain/result.js";
import { createJavaScriptSemanticTraceEvidence } from "./JavaScriptApplicationWorkflowEvidence.js";
import type { ApplicationWorkflowExecution } from "./JavaScriptApplicationWorkflowService.js";
const OPERATION = "trace_javascript_semantics" as const;
/** Trace semantic relations from input already parsed by a trusted adapter. */
export const traceJavaScriptSemanticsEvidenceValidated = (
input: z.output<typeof traceJavaScriptSemanticsInputSchema>,
): Result<Evidence, AnalysisError> => {
/** Resolve and authenticate one application source before tracing semantic relations. */
export const traceJavaScriptSemanticsEvidence = (
rawInput: unknown,
lookup?: EvidenceLookup,
options: Pick<ExecutionOptions, "signal"> = {},
): Result<
ApplicationWorkflowExecution<JavaScriptSemanticTraceResult>,
AnalysisError
> => {
const request = resolveEvidenceRequest(
OPERATION,
rawInput,
traceJavaScriptSemanticsRequestSchema,
lookup,
options,
);
if (!request.ok) return request;
const input = request.value.input;
const sourceResult = parseApplicationGraphEvidence(input.application, [
"application",
]);
@@ -36,7 +51,7 @@ export const traceJavaScriptSemanticsEvidenceValidated = (
path: ["application"],
reason: "invalid_value",
expected:
"inline Evidence from analyze_javascript_application with a semantic graph",
"Evidence from analyze_javascript_application with a semantic graph",
},
]),
);
@@ -47,16 +62,15 @@ export const traceJavaScriptSemanticsEvidenceValidated = (
evidence_links: [source.evidence.evidence_id],
};
const { allowed_relations, ...queryParameters } = input.query;
return ok(
createJavaScriptSemanticTraceEvidence(
{
application_evidence_id: source.evidence.evidence_id,
query:
allowed_relations === undefined
? queryParameters
: { ...queryParameters, allowed_relations },
},
result,
),
const evidence = createJavaScriptSemanticTraceEvidence(
{
application_evidence_id: source.evidence.evidence_id,
query:
allowed_relations === undefined
? queryParameters
: { ...queryParameters, allowed_relations },
},
result,
);
return ok({ evidence, result, sources: [source.evidence] });
};