refactor(evidence): centralize JSON payload admission

Give ordinary Evidence creation an explicit unknown-payload input contract
while retaining the strong JSON contract for producer helpers and cooperative
immutable creation. Keep schema admission, input snapshotting and identity
hashing with the Evidence owner.

Remove 32 generic JSON preparses that only fed ordinary Evidence construction.
Preserve semantic format validation, selected-source bindings, standalone
JSON boundaries, typed executions and scenario digest contracts. Invalid JSON
now reports its Evidence parameters/normalized_result/raw_result prefix.

Validation: fresh runtime/catalog build, 560 focused and README tests passed,
4 platform-specific cases skipped, full static/docs checks, test discovery,
duplication and diff checks. New regressions cover omitted semantic optionals,
raw-result defaults and nested undefined refusal without input mutation.
Installed providers, real browsers/Frida/JADX and Linux-only recovery remain
unverified; boundary providers are authored fixtures.
This commit is contained in:
morluto committed 2026-10-25 05:01:36 +08:00
1 parent 835904e4ee
commit 58fb824105
26 files changed
+162 -69

No files matched your search

+11
View File
@@ -241,6 +241,17 @@ Put provider protocols/parsing in adapters and shared CLI/MCP workflows in the
application layer. Share Evidence provenance, unknown projection, and session
retention semantics; matching payloads alone do not establish parity.
Let `createEvidence` own JSON validation and snapshotting of ordinary observation
payloads. `EvidenceObservationInput` accepts semantically parsed parameters,
results, and raw results whose JSON validity still needs admission. Keep format,
selection, and identity validation at their producing boundary. Invalid JSON
issues are rooted at `parameters`, `normalized_result`, or `raw_result` in the
Evidence envelope.
`EvidenceObservation` retains the stronger JSON contract used by producer
helpers and `createImmutableEvidenceSteps`. The cooperative constructor also
requires an authenticated immutable result; preserve that ownership proof.
Measure the resource before choosing a budget and enforce it before the costly
step. Account for value alternatives, trace-frame products, retained records,
serialization expansion, and temporary-file growth separately. Derive facet
+1 -2
View File
@@ -4,7 +4,6 @@ import {
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
import type {
InspectWebPageInput,
@@ -77,7 +76,7 @@ export const createBrowserEvidence = (
predicateType: browserPredicate(operation),
operation,
parameters: browserParameters(input, result),
result: jsonValueSchema.parse(result),
result,
confidence: "observed",
authority: "external-service",
environment:
+2 -2
View File
@@ -7,7 +7,7 @@ import {
type Evidence,
type EvidenceObservation,
} from "../domain/evidence.js";
import { jsonObjectSchema, jsonValueSchema } from "../domain/jsonValue.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
const browserScenarioParameters = (
scenario: BrowserScenario,
@@ -26,7 +26,7 @@ export const createBrowserScenarioEvidence = (
predicateType: "rea.browser-scenario-capture",
operation: "capture_browser_scenario",
parameters: browserScenarioParameters(scenario),
result: jsonValueSchema.parse(capture),
result: capture,
confidence: "observed",
authority: "controlled-replay",
environment: {
@@ -12,7 +12,6 @@ import {
createEvidenceBundle,
type EvidenceBundle,
} from "../domain/evidenceBundle.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import {
reconstructionObligationLedgerSchema,
type ReconstructionObligationLedgerInput,
@@ -47,12 +46,10 @@ export const processEvidence = (
predicateType: "rea.process-capture",
operation: "capture_process_scenario",
parameters: {},
result: jsonValueSchema.parse(
processCaptureSchema.parse({
...EMPTY_PROCESS_CAPTURE_EXAMPLE,
...overrides,
}),
),
result: processCaptureSchema.parse({
...EMPTY_PROCESS_CAPTURE_EXAMPLE,
...overrides,
}),
confidence: "observed",
authority: "controlled-replay",
});
@@ -70,9 +67,7 @@ export const boundProofEvidence = (
predicateType: "rea.reconstruction-proof",
operation: "verify_reconstruction_obligations",
parameters: {},
result: jsonValueSchema.parse(
reconstructionObligationProofSchema.parse(result),
),
result: reconstructionObligationProofSchema.parse(result),
confidence: "observed",
authority,
},
+1 -1
View File
@@ -261,7 +261,7 @@ export class WebModuleTraceService {
},
{
operation: OPERATION,
parameters: jsonObjectSchema.parse(input),
parameters: input,
result: normalized.data,
rawResult: resolution?.rawResult ?? null,
confidence: "derived",
+1 -2
View File
@@ -7,7 +7,6 @@ import {
AnalysisOutputError,
} from "../domain/analysisErrorCore.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../domain/result.js";
import {
@@ -162,7 +161,7 @@ export class WebRuntimeService {
createEvidence(undefined, this.provider.identity(), {
predicateType: `rea.${operation.replaceAll("_", "-")}`,
operation,
parameters: jsonObjectSchema.parse(input),
parameters: input,
result,
confidence: "observed",
authority: "external-service",
+1 -2
View File
@@ -21,7 +21,6 @@ import { AnalysisError } from "../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
import { err, ok, type Result } from "../domain/result.js";
@@ -136,7 +135,7 @@ export const exportWebScriptsValidated = async (
capture_path: input.capture_path,
output_directory: input.output_directory,
},
result: jsonValueSchema.parse(result),
result,
rawResult: null,
confidence: "derived",
authority: "historical-reference",
+1 -2
View File
@@ -9,7 +9,6 @@ import {
} from "../domain/analysisErrorCore.js";
import { createEvidence, type Evidence } from "../domain/evidence.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { err, ok, type Result } from "../domain/result.js";
import {
selectedWebScriptArtifactsSchema,
@@ -171,7 +170,7 @@ export class WebSourceLocationService {
},
{
operation: OPERATION,
parameters: jsonObjectSchema.parse(input),
parameters: input,
result: normalized.data,
rawResult: { source_map_text: map.text },
confidence: "derived",
@@ -2,7 +2,6 @@ import { setImmediate } from "node:timers/promises";
import { dispatchQueuedInterrupts } from "../../process/queuedInterrupts.js";
import { readImmutableEvidenceBundle } from "../EvidenceBundleFiles.js";
import { INSPECT_ANALYSIS_VIEW_OPERATION } from "../../domain/analysisView/analysisViewErrors.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import { ANALYSIS_VIEW_PROVIDER } from "../../domain/investigationProviders.js";
import type { EvidenceLookup } from "../EvidenceInputResolver.js";
@@ -346,9 +345,9 @@ const createAnalysisViewEvidence = (
operation: INSPECT_ANALYSIS_VIEW_OPERATION,
parameters: {
parent_evidence_id: parent.evidence_id,
view: jsonValueSchema.parse(input.view),
view: input.view,
},
result: jsonValueSchema.parse(result),
result,
rawResult: null,
confidence:
// Grouping is whole-capture, so any templated group or parameter makes the result inferred;
@@ -11,7 +11,6 @@ import {
import { AnalysisCancelledError } from "../../domain/analysisErrorCore.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../../domain/evidence.js";
import { jsonObjectSchema } from "../../domain/jsonValue.js";
import { err, type Result } from "../../domain/result.js";
import { completeProviderEvidence } from "../ProviderOperationExecution.js";
@@ -62,7 +61,7 @@ export class AndroidAnalysisService {
execution.provider,
{
operation,
parameters: jsonObjectSchema.parse(request.data.input),
parameters: request.data.input,
result: execution.result,
rawResult: execution.rawResult,
limitations: execution.limitations,
@@ -3,7 +3,6 @@ import { access, stat } from "node:fs/promises";
import { setTimeout as delay } from "node:timers/promises";
import { createEvidence, type Evidence } from "../../domain/evidence.js";
import { jsonObjectSchema, jsonValueSchema } from "../../domain/jsonValue.js";
import {
resolvedAnalysisError,
type AnalysisError,
@@ -458,8 +457,8 @@ const fridaEvidence = (
{
predicateType: "rea.frida.instrumentation-observation",
operation,
parameters: jsonObjectSchema.parse(parameters),
result: jsonValueSchema.parse(result),
parameters,
result,
...(script?.sourceRepresentation === undefined
? {}
: {
@@ -4,7 +4,7 @@ import type { CanonicalElectronActiveObservationInput } from "./ElectronActiveOb
import type { Evidence, EvidenceObservation } from "../../domain/evidence.js";
import { createEvidence } from "../../domain/evidence.js";
import type { ElectronActiveObservationResult } from "../../domain/javascript/electronActiveObservation.js";
import { jsonObjectSchema, jsonValueSchema } from "../../domain/jsonValue.js";
import { jsonObjectSchema } from "../../domain/jsonValue.js";
/** Commit the selected Electron experiment and its observed result. */
export const createElectronActiveEvidence = (
@@ -16,7 +16,7 @@ export const createElectronActiveEvidence = (
predicateType: "rea.electron-active-scenario",
operation: "capture_electron_scenario",
parameters: parameters(input),
result: jsonValueSchema.parse(result),
result,
confidence: "observed",
authority: "controlled-replay",
environment: {
@@ -11,7 +11,6 @@ import {
javascriptRecoveryInputSchema,
javascriptRecoveryResultSchema,
} from "../../domain/javascript/javascriptRecovery.js";
import { jsonObjectSchema, jsonValueSchema } from "../../domain/jsonValue.js";
import { analysisInputErrorFromIssues } from "../../domain/inputIssueProjection.js";
import { err, type Result } from "../../domain/result.js";
import type { ExecutionOptions } from "../AnalysisProvider.js";
@@ -115,8 +114,8 @@ export class JavaScriptRecoveryService {
execution.value.provider,
{
operation: OPERATION,
parameters: jsonObjectSchema.parse(parsed.data),
result: jsonValueSchema.parse(result.data),
parameters: parsed.data,
result: result.data,
rawResult: execution.value.rawResult,
locations: execution.value.locations,
limitations: execution.value.limitations,
@@ -10,7 +10,6 @@ import type {
ListJavaScriptRuntimeTargetsInput,
ObserveJavaScriptRuntimeInput,
} from "../../domain/javascript/javascriptRuntimeObservation.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
type RuntimeObservationOperation =
| "list_javascript_runtime_targets"
@@ -30,7 +29,7 @@ export const createJavaScriptRuntimeObservationEvidence = (
: "rea.javascript-runtime-observation",
operation,
parameters: parameters(input),
result: jsonValueSchema.parse(result),
result,
rawResult: null,
confidence: "observed",
authority: "external-service",
+1 -2
View File
@@ -10,7 +10,6 @@ import {
PROCESS_PROVIDER,
isProcessEvidenceProvider,
} from "../../domain/process/processEvidenceProvider.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import {
safeParseProcessCapture,
type ProcessCapture,
@@ -91,7 +90,7 @@ export const createProcessCaptureEvidence = (
predicateType: PROCESS_CAPTURE_EVIDENCE.predicate,
operation: PROCESS_CAPTURE_EVIDENCE.operation,
parameters: processEvidenceParameters(scenario, capture.manifest.platform),
result: jsonValueSchema.parse(capture),
result: capture,
confidence: "observed",
authority: "controlled-replay",
environment: {
@@ -23,7 +23,6 @@ import {
} from "../../domain/sqlite/sqliteDatabase.js";
import { analysisInputErrorFromIssues } from "../../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../../domain/result.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
const OPERATION = "inspect_sqlite_database";
@@ -115,7 +114,7 @@ export class SqliteDatabaseService {
createEvidence(execution.subject, execution.provider, {
operation: OPERATION,
parameters: sqliteInspectionParameters(input.data),
result: jsonValueSchema.parse(report.data),
result: report.data,
...(execution.rawResult === null
? {}
: { rawResult: execution.rawResult }),
+2 -3
View File
@@ -1,5 +1,4 @@
import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { FUNCTION_COMPARISON_PROVIDER } from "../domain/comparisonEvidenceIdentity.js";
import { compareProcessCaptureEvidence } from "../domain/process/processComparisonEvidence.js";
import { PROCESS_PROVIDER } from "../domain/process/processEvidenceProvider.js";
@@ -31,7 +30,7 @@ export const FUNCTION_COMPARISON_EVIDENCE = createEvidence(
left_evidence_id: left.value.evidence.evidence_id,
right_evidence_id: right.value.evidence.evidence_id,
},
result: jsonValueSchema.parse(comparison),
result: comparison,
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
@@ -48,7 +47,7 @@ const captureEvidence = (scenario: string) =>
predicateType: "rea.process-capture",
operation: "capture_process_scenario",
parameters: { scenario },
result: jsonValueSchema.parse(capture),
result: capture,
confidence: "observed",
authority: "controlled-replay",
environment: {
+2 -2
View File
@@ -7,7 +7,7 @@ import {
type EvidenceSubjectTarget,
} from "./evidence.js";
import type { AnalysisProfileCommitment } from "./analysisProfile.js";
import { jsonObjectSchema, type JsonValue } from "./jsonValue.js";
import type { JsonValue } from "./jsonValue.js";
import type { RelationshipCoverage } from "./relationshipCoverage.js";
/** Provider observations that can be committed to Evidence. */
@@ -44,7 +44,7 @@ export const createAnalysisExecutionEvidence = (
execution.provider,
{
operation,
parameters: jsonObjectSchema.parse(input),
parameters: input,
result: execution.result,
rawResult: execution.rawResult,
limitations: execution.limitations,
+96
View File
@@ -138,6 +138,102 @@ it("projects known provider fields and preserves open JSON payloads", () => {
expect(parseEvidence(evidence)).toEqual(evidence);
});
it("admits typed semantic payloads with omitted optional facts without changing inputs or identity", () => {
interface Selection {
readonly procedure: string;
readonly address?: string;
}
interface SymbolRow {
readonly name: string;
readonly size?: number;
}
interface NativeRecord {
readonly producer: string;
readonly diagnostic?: string;
}
const parameters: Selection = { procedure: "main" };
const row: SymbolRow = { name: "main" };
const result = { symbols: [row] };
const rawResult: NativeRecord = { producer: "authored fixture" };
const evidence = createEvidence(TARGET, PROVIDER, {
operation: "inspect",
parameters,
result,
rawResult,
});
const equivalent = createEvidence(TARGET, PROVIDER, {
operation: "inspect",
parameters: { procedure: "main" },
result: { symbols: [{ name: "main" }] },
rawResult: { producer: "authored fixture" },
});
expect(evidence).toEqual(equivalent);
expect(evidence.evidence_id).toBe(equivalent.evidence_id);
expect(parameters).toEqual({ procedure: "main" });
expect(result).toEqual({ symbols: [{ name: "main" }] });
expect(result.symbols[0]).toBe(row);
expect(rawResult).toEqual({ producer: "authored fixture" });
expect(Object.hasOwn(parameters, "address")).toBe(false);
expect(Object.hasOwn(row, "size")).toBe(false);
expect(Object.hasOwn(rawResult, "diagnostic")).toBe(false);
expect(Object.isFrozen(parameters)).toBe(false);
expect(Object.isFrozen(result)).toBe(false);
expect(Object.isFrozen(row)).toBe(false);
expect(Object.isFrozen(rawResult)).toBe(false);
});
it("keeps an omitted, undefined, or null raw payload equivalent", () => {
const observation = { operation: "inspect", parameters: {}, result: true };
const omitted = createEvidence(TARGET, PROVIDER, observation);
const explicitUndefined = createEvidence(TARGET, PROVIDER, {
...observation,
rawResult: undefined,
});
const explicitNull = createEvidence(TARGET, PROVIDER, {
...observation,
rawResult: null,
});
expect(omitted.raw_result).toBeNull();
expect(explicitUndefined).toEqual(omitted);
expect(explicitNull).toEqual(omitted);
});
it.each([
{ field: "parameters", prefix: "parameters" },
{ field: "result", prefix: "normalized_result" },
{ field: "rawResult", prefix: "raw_result" },
])(
"rejects explicit nested undefined in $field at its Evidence prefix",
({ field, prefix }) => {
const invalid = { nested: { value: undefined } };
let failure: unknown;
try {
createEvidence(TARGET, PROVIDER, {
operation: "inspect",
parameters: {},
result: true,
[field]: invalid,
});
} catch (cause: unknown) {
failure = cause;
}
expect(failure).toMatchObject({
name: "ZodError",
issues: [
{
path: [prefix],
message: expect.stringContaining("JSON"),
},
],
});
expect(Object.hasOwn(invalid.nested, "value")).toBe(true);
expect(invalid.nested.value).toBeUndefined();
},
);
it("preserves identity and bytes when reusing an owned immutable result", () => {
const value = { nested: { values: ["observed", 1] } };
const mutable = createEvidence(TARGET, PROVIDER, {
+16 -8
View File
@@ -242,13 +242,14 @@ type ExecutionEnvironment = z.infer<typeof executionEnvironmentSchema>;
export type EvidenceProvider = Readonly<z.output<typeof providerSchema>>;
export interface EvidenceObservation {
/** Payloads admitted and snapshotted by the ordinary Evidence constructor. */
export interface EvidenceObservationInput {
readonly predicateType?: string;
readonly operation: string;
readonly parameters: Readonly<Record<string, JsonValue>>;
readonly result: JsonValue;
readonly parameters: unknown;
readonly result: unknown;
readonly analysisProfile?: AnalysisProfileCommitment;
readonly rawResult?: JsonValue;
readonly rawResult?: unknown;
readonly confidence?: "observed" | "derived" | "inferred";
readonly authority?: EvidenceAuthority;
readonly environment?: ExecutionEnvironment | null;
@@ -260,6 +261,13 @@ export interface EvidenceObservation {
readonly evidenceLinks?: readonly string[];
}
/** Producer facts that already promise JSON, including cooperative Evidence input. */
export interface EvidenceObservation extends EvidenceObservationInput {
readonly parameters: Readonly<Record<string, JsonValue>>;
readonly result: JsonValue;
readonly rawResult?: JsonValue;
}
type EvidenceWithoutId = Omit<EvidenceSchemaValue, "evidence_id">;
/** Content committed by an Evidence ID, excluding local request/display metadata. */
@@ -403,11 +411,11 @@ export interface EvidenceCreationOptions {
readonly immutable?: boolean;
}
/** Build deterministic Evidence from an immutable artifact subject. */
/** Admit payloads into deterministic Evidence bound to an immutable artifact subject. */
export const createEvidence = (
target: EvidenceSubjectTarget | BinaryTarget | undefined,
provider: EvidenceProvider,
observation: EvidenceObservation,
observation: EvidenceObservationInput,
options?: EvidenceCreationOptions,
): Evidence => {
const { normalized, sharedResult } = normalizeEvidenceObservation(
@@ -460,7 +468,7 @@ export function* createImmutableEvidenceSteps(
const normalizeEvidenceObservation = (
target: EvidenceSubjectTarget | BinaryTarget | undefined,
provider: EvidenceProvider,
observation: EvidenceObservation,
observation: EvidenceObservationInput,
) => {
const subject =
target === undefined
@@ -509,7 +517,7 @@ const normalizeEvidenceObservation = (
: { relationship_coverage: observation.relationshipCoverage }),
locations: [...(observation.locations ?? [])],
evidence_links: [...(observation.evidenceLinks ?? [])],
} satisfies JsonValue;
};
const sharedResult =
typeof observation.result === "object" &&
observation.result !== null &&
+2 -2
View File
@@ -1,5 +1,5 @@
import { createEvidence } from "../evidence.js";
import { jsonObjectSchema, type JsonValue } from "../jsonValue.js";
import type { JsonValue } from "../jsonValue.js";
import type { PcapRequest } from "./pcapAnalysis.js";
/** Domain facts needed by both successful and retained partial observations. */
@@ -21,7 +21,7 @@ export const createPcapEvidence = (
) =>
createEvidence(observation.subject ?? undefined, observation.provider, {
operation: request.operation,
parameters: jsonObjectSchema.parse(request.input),
parameters: request.input,
result: observation.result,
rawResult: observation.rawResult,
limitations: observation.limitations,
@@ -1,5 +1,4 @@
import { createEvidence, type Evidence } from "../evidence.js";
import { jsonValueSchema } from "../jsonValue.js";
import type { ProcessCapture } from "./processCaptureParsing.js";
import {
compareProcessCaptures,
@@ -37,9 +36,9 @@ export const compareProcessCaptureEvidence = (
: { max_capture_age_ms: options.maxCaptureAgeMs }),
...(options.traceSpecification === undefined
? {}
: { trace_spec: jsonValueSchema.parse(options.traceSpecification) }),
: { trace_spec: options.traceSpecification }),
},
result: jsonValueSchema.parse(comparison),
result: comparison,
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
+1 -2
View File
@@ -6,7 +6,6 @@ import { compareArtifacts } from "../domain/artifactComparison.js";
import { ARTIFACT_COMPARISON_PROVIDER } from "../domain/comparisonEvidenceIdentity.js";
import { createEvidence } from "../domain/evidence.js";
import { readEvidence } from "../domain/evidenceValidation.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { resolveArtifactComparisonEvidence } from "../application/artifacts/ArtifactComparisonEvidence.js";
import type { RecordUnknownInput } from "../domain/residualUnknown.js";
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
@@ -78,7 +77,7 @@ export const registerArtifactComparisonTool = (
left_evidence_ids: leftEvidenceIds,
right_evidence_ids: rightEvidenceIds,
},
result: jsonValueSchema.parse(comparison),
result: comparison,
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
+1 -2
View File
@@ -5,7 +5,6 @@ import { readImmutableEvidenceBundle } from "../application/EvidenceBundleFiles.
import { toolContract } from "../contracts/toolContracts.js";
import { compareBundles } from "../domain/bundleComparison.js";
import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { runDerivedOperation } from "./runDerivedOperation.js";
import { recordEvidenceSources } from "../application/investigation/recordEvidenceSources.js";
import { BUNDLE_COMPARISON_PROVIDER } from "../domain/investigationProviders.js";
@@ -82,7 +81,7 @@ export const registerBundleComparisonTool = (
right_bundle_sha256: comparison.right_bundle_sha256,
record_pairs: input.record_pairs,
},
result: jsonValueSchema.parse(comparison),
result: comparison,
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
+1 -2
View File
@@ -6,7 +6,6 @@ import { toolContract } from "../contracts/toolContracts.js";
import { createEvidence } from "../domain/evidence.js";
import { parseFunctionEvidence } from "../domain/functionDossierEvidence.js";
import { FUNCTION_COMPARISON_PROVIDER } from "../domain/comparisonEvidenceIdentity.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import type { RecordUnknownInput } from "../domain/residualUnknown.js";
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
import { recordEvidenceSources } from "../application/investigation/recordEvidenceSources.js";
@@ -84,7 +83,7 @@ export const registerFunctionComparisonTool = (
left_evidence_id: leftEvidence.evidence_id,
right_evidence_id: rightEvidence.evidence_id,
},
result: jsonValueSchema.parse(comparison),
result: comparison,
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
+4 -5
View File
@@ -6,7 +6,6 @@ import { toolContract } from "../contracts/toolContracts.js";
import { buildCallPath } from "../domain/callPath.js";
import { findChangedBehavior } from "../domain/changedBehavior.js";
import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { correlateStaticAndRuntime } from "../domain/staticRuntimeCorrelation.js";
import {
comparisonClosure,
@@ -88,7 +87,7 @@ const registerChangedBehavior = (
parameters: {
comparison_evidence_ids: [...comparisonEvidenceIds],
},
result: jsonValueSchema.parse(result),
result,
confidence: "derived",
authority: "analyst-inference",
limitations: result.limitations,
@@ -161,7 +160,7 @@ const registerCallPath = (
start: input.start.address,
goal: input.goal.address,
},
result: jsonValueSchema.parse(result),
result,
confidence: "derived",
authority: "analyst-inference",
limitations: result.limitations,
@@ -236,7 +235,7 @@ const registerStaticRuntime = (
parameters: {
mapping_count: input.mappings.length,
},
result: jsonValueSchema.parse(result),
result,
confidence: "inferred",
authority: "analyst-inference",
limitations: result.limitations,
@@ -311,7 +310,7 @@ const registerReconstruction = (
({ claim_id: id }) => id,
),
},
result: jsonValueSchema.parse(result),
result,
confidence: "derived",
authority: "analyst-inference",
limitations: result.limitations,