mirror of
https://github.com/morluto/rea
synced 2026-10-27 06:33:32 -04:00
735c10059c
Move each error family out of domain/errors.ts into its own module (base, core, provider selection/adapter, browser observation, artifact, evidence, unknown registry, hopper, configuration) and relocate AnalysisErrorProjection to analysisErrorProjection. Migrate all 162 importers to the owning modules and delete errors.ts. No re-export shims; behavior is unchanged.
94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
import { z } from "zod";
|
|
|
|
import {
|
|
AnalysisInputError,
|
|
AnalysisProtocolError,
|
|
} from "../domain/analysisErrorCore.js";
|
|
import { type AnalysisError } from "../domain/analysisErrorBase.js";
|
|
import {
|
|
createEvidence,
|
|
type Evidence,
|
|
type EvidenceProvider,
|
|
type EvidenceSubjectTarget,
|
|
} from "../domain/evidence.js";
|
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
import { err, ok, type Result } from "../domain/result.js";
|
|
|
|
interface InventoryProjectionInput {
|
|
readonly inventory_evidence: readonly Evidence[];
|
|
readonly limits?: unknown;
|
|
}
|
|
|
|
interface InventoryProjectionResult {
|
|
readonly root_sha256: string;
|
|
readonly source_evidence_ids: readonly string[];
|
|
readonly limitations: readonly string[];
|
|
}
|
|
|
|
interface InventoryProjectionOptions<
|
|
Input extends InventoryProjectionInput,
|
|
Output extends InventoryProjectionResult,
|
|
> {
|
|
readonly rawInput: unknown;
|
|
readonly schema: z.ZodType<Input>;
|
|
readonly project: (input: Input) => Output;
|
|
readonly operation: string;
|
|
readonly predicateType: string;
|
|
readonly provider: EvidenceProvider;
|
|
readonly subjectFormat: (first: Evidence) => EvidenceSubjectTarget["format"];
|
|
readonly protocolError: string;
|
|
}
|
|
|
|
/** Parse one inventory projection and wrap its deterministic result in Evidence. */
|
|
export const projectInventoryEvidence = <
|
|
Input extends InventoryProjectionInput,
|
|
Output extends InventoryProjectionResult,
|
|
>(
|
|
options: InventoryProjectionOptions<Input, Output>,
|
|
): Result<Evidence, AnalysisError> => {
|
|
const parsed = options.schema.safeParse(options.rawInput);
|
|
if (!parsed.success)
|
|
return err(
|
|
new AnalysisInputError(options.operation, { cause: parsed.error }),
|
|
);
|
|
try {
|
|
const result = options.project(parsed.data);
|
|
const first = parsed.data.inventory_evidence[0];
|
|
return ok(
|
|
createEvidence(
|
|
first?.subject === null || first?.subject === undefined
|
|
? undefined
|
|
: {
|
|
path: first.subject.local_path,
|
|
sha256: result.root_sha256,
|
|
format: options.subjectFormat(first),
|
|
},
|
|
options.provider,
|
|
{
|
|
predicateType: options.predicateType,
|
|
operation: options.operation,
|
|
parameters: {
|
|
inventory_evidence_ids: [...result.source_evidence_ids],
|
|
...("limits" in parsed.data && parsed.data.limits !== undefined
|
|
? { limits: jsonValueSchema.parse(parsed.data.limits) }
|
|
: {}),
|
|
},
|
|
result: jsonValueSchema.parse(result),
|
|
rawResult: null,
|
|
confidence: "inferred",
|
|
authority: "analyst-inference",
|
|
environment: null,
|
|
limitations: result.limitations,
|
|
evidenceLinks: result.source_evidence_ids,
|
|
},
|
|
),
|
|
);
|
|
} catch (cause: unknown) {
|
|
return err(
|
|
cause instanceof TypeError || cause instanceof z.ZodError
|
|
? new AnalysisInputError(options.operation, { cause })
|
|
: new AnalysisProtocolError(options.protocolError, { cause }),
|
|
);
|
|
}
|
|
};
|